diff --git a/.hgtags b/.hgtags index 7a7bbeb39e4..afdf45c8e30 100644 --- a/.hgtags +++ b/.hgtags @@ -149,3 +149,4 @@ e8f03541af27e38aafb619b96863e17f65ffe53b jdk8-b22 0071a6d64113a35ba345bb1580c256de5ce17d3e jdk8-b25 6c805d8ed4e5449ea5e4d158c7bdbd7b0b70efd1 jdk8-b26 c51754cddc037b9609e202b9ed38363d8683e7a8 jdk8-b27 +16ba58282d117247f480aae7a79b88141ade52a3 jdk8-b28 diff --git a/.hgtags-top-repo b/.hgtags-top-repo index 650464aa130..66162368cb1 100644 --- a/.hgtags-top-repo +++ b/.hgtags-top-repo @@ -149,3 +149,4 @@ cc771d92284f71765eca14d6d08703c4af254c04 jdk8-b21 221a378e06a326f45e5d89e2123cd6323e0181d1 jdk8-b25 2accafff224ae39caf5f532c305251ba624bf2c0 jdk8-b26 1533dfab9903e4edcfead3b0192643f38c418b9b jdk8-b27 +6e2541d60f4e342b5b67140271d7611643929dc3 jdk8-b28 diff --git a/corba/.hgtags b/corba/.hgtags index 528e8770d13..2a838257a4c 100644 --- a/corba/.hgtags +++ b/corba/.hgtags @@ -149,3 +149,4 @@ b98f0e6dddf987df565029a1f58417fc1844c3f3 jdk8-b24 e45d6b406d5f91ff5256a5c82456ab1e7eb8becd jdk8-b25 79f709a099f40c08f76567fa6d813f9009a69826 jdk8-b26 4fffe75e4edd39a2517f10b743941bf94edb143d jdk8-b27 +2082eb35d49a9c2aab90b8d4fd31cefb7a23b82e jdk8-b28 diff --git a/hotspot/.hgtags b/hotspot/.hgtags index 7166d465099..707d07c8f9c 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -226,3 +226,5 @@ f92a171cf0071ca6c3fa8231d7d570377f8b2f4d hs23-b16 931e5f39e365a0d550d79148ff87a7f9e864d2e1 hs23-b16 3b24e7e01d20ca590d0f86b1222bb7c3f1a2aa2d jdk8-b27 975c4105f1e2ef1190a75b77124033f1fd4290b5 hs24-b01 +b183b0863611b85dbac16f3b08b40ba978756d19 jdk8-b28 +030b5306d60f140e822e4a6d301744cb110ff0c8 hs24-b02 diff --git a/hotspot/make/bsd/makefiles/buildtree.make b/hotspot/make/bsd/makefiles/buildtree.make index 960a382bb11..ccc812775c1 100644 --- a/hotspot/make/bsd/makefiles/buildtree.make +++ b/hotspot/make/bsd/makefiles/buildtree.make @@ -58,6 +58,7 @@ # needs to be set here since this Makefile doesn't include defs.make OS_VENDOR:=$(shell uname -s) +-include $(SPEC) include $(GAMMADIR)/make/scm.make include $(GAMMADIR)/make/altsrc.make @@ -247,6 +248,8 @@ flags.make: $(BUILDTREE_MAKE) ../shared_dirs.lst echo "HOTSPOT_EXTRA_SYSDEFS\$$(HOTSPOT_EXTRA_SYSDEFS) = $(HOTSPOT_EXTRA_SYSDEFS)" && \ echo "SYSDEFS += \$$(HOTSPOT_EXTRA_SYSDEFS)"; \ echo; \ + [ -n "$(SPEC)" ] && \ + echo "include $(SPEC)"; \ echo "include \$$(GAMMADIR)/make/$(OS_FAMILY)/makefiles/$(VARIANT).make"; \ echo "include \$$(GAMMADIR)/make/$(OS_FAMILY)/makefiles/$(COMPILER).make"; \ ) > $@ diff --git a/hotspot/make/bsd/makefiles/gcc.make b/hotspot/make/bsd/makefiles/gcc.make index d7a6422eb40..a73397bf0f7 100644 --- a/hotspot/make/bsd/makefiles/gcc.make +++ b/hotspot/make/bsd/makefiles/gcc.make @@ -27,53 +27,57 @@ OS_VENDOR = $(shell uname -s) #------------------------------------------------------------------------ # CC, CXX & AS -# When cross-compiling the ALT_COMPILER_PATH points -# to the cross-compilation toolset -ifdef CROSS_COMPILE_ARCH - CXX = $(ALT_COMPILER_PATH)/g++ - CC = $(ALT_COMPILER_PATH)/gcc - HOSTCXX = g++ - HOSTCC = gcc -else ifneq ($(OS_VENDOR), Darwin) - CXX = g++ - CC = gcc - HOSTCXX = $(CXX) - HOSTCC = $(CC) +# If a SPEC is not set already, then use these defaults. +ifeq ($(SPEC),) + # When cross-compiling the ALT_COMPILER_PATH points + # to the cross-compilation toolset + ifdef CROSS_COMPILE_ARCH + CXX = $(ALT_COMPILER_PATH)/g++ + CC = $(ALT_COMPILER_PATH)/gcc + HOSTCXX = g++ + HOSTCC = gcc + else ifneq ($(OS_VENDOR), Darwin) + CXX = g++ + CC = gcc + HOSTCXX = $(CXX) + HOSTCC = $(CC) + endif + + # i486 hotspot requires -mstackrealign on Darwin. + # llvm-gcc supports this in Xcode 3.2.6 and 4.0. + # gcc-4.0 supports this on earlier versions. + # Prefer llvm-gcc where available. + ifeq ($(OS_VENDOR), Darwin) + ifeq ($(origin CXX), default) + CXX = llvm-g++ + endif + ifeq ($(origin CC), default) + CC = llvm-gcc + endif + + ifeq ($(ARCH), i486) + LLVM_SUPPORTS_STACKREALIGN := $(shell \ + [ "0"`llvm-gcc -v 2>&1 | grep LLVM | sed -E "s/.*LLVM build ([0-9]+).*/\1/"` -gt "2333" ] \ + && echo true || echo false) + + ifeq ($(LLVM_SUPPORTS_STACKREALIGN), true) + CXX32 ?= llvm-g++ + CC32 ?= llvm-gcc + else + CXX32 ?= g++-4.0 + CC32 ?= gcc-4.0 + endif + CXX = $(CXX32) + CC = $(CC32) + endif + + HOSTCXX = $(CXX) + HOSTCC = $(CC) + endif + + AS = $(CC) -c -x assembler-with-cpp endif -# i486 hotspot requires -mstackrealign on Darwin. -# llvm-gcc supports this in Xcode 3.2.6 and 4.0. -# gcc-4.0 supports this on earlier versions. -# Prefer llvm-gcc where available. -ifeq ($(OS_VENDOR), Darwin) - ifeq ($(origin CXX), default) - CXX = llvm-g++ - endif - ifeq ($(origin CC), default) - CC = llvm-gcc - endif - - ifeq ($(ARCH), i486) - LLVM_SUPPORTS_STACKREALIGN := $(shell \ - [ "0"`llvm-gcc -v 2>&1 | grep LLVM | sed -E "s/.*LLVM build ([0-9]+).*/\1/"` -gt "2333" ] \ - && echo true || echo false) - - ifeq ($(LLVM_SUPPORTS_STACKREALIGN), true) - CXX32 ?= llvm-g++ - CC32 ?= llvm-gcc - else - CXX32 ?= g++-4.0 - CC32 ?= gcc-4.0 - endif - CXX = $(CXX32) - CC = $(CC32) - endif - - HOSTCXX = $(CXX) - HOSTCC = $(CC) -endif - -AS = $(CC) -c -x assembler-with-cpp # -dumpversion in gcc-2.91 shows "egcs-2.91.66". In later version, it only # prints the numbers (e.g. "2.95", "3.2.1") diff --git a/hotspot/make/bsd/makefiles/sparcWorks.make b/hotspot/make/bsd/makefiles/sparcWorks.make index 81de9c33baa..c87f5044096 100644 --- a/hotspot/make/bsd/makefiles/sparcWorks.make +++ b/hotspot/make/bsd/makefiles/sparcWorks.make @@ -25,12 +25,15 @@ #------------------------------------------------------------------------ # CC, CXX & AS -CXX = CC -CC = cc -AS = $(CC) -c +# If a SPEC is not set already, then use these defaults. +ifeq ($(SPEC),) + CXX = CC + CC = cc + AS = $(CC) -c -HOSTCXX = $(CXX) -HOSTCC = $(CC) + HOSTCXX = $(CXX) + HOSTCC = $(CC) +endif ARCHFLAG = $(ARCHFLAG/$(BUILDARCH)) ARCHFLAG/i486 = -m32 diff --git a/hotspot/make/defs.make b/hotspot/make/defs.make index a0aa0e5c859..ac7268a96c5 100644 --- a/hotspot/make/defs.make +++ b/hotspot/make/defs.make @@ -24,6 +24,11 @@ # The common definitions for hotspot builds. +# Optionally include SPEC file generated by configure. +ifneq ($(SPEC),) + include $(SPEC) +endif + # Default to verbose build logs (show all compile lines): MAKE_VERBOSE=y diff --git a/hotspot/make/hotspot_version b/hotspot/make/hotspot_version index f67badd6da0..6cc9716c948 100644 --- a/hotspot/make/hotspot_version +++ b/hotspot/make/hotspot_version @@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2011 HS_MAJOR_VER=24 HS_MINOR_VER=0 -HS_BUILD_NUMBER=01 +HS_BUILD_NUMBER=02 JDK_MAJOR_VER=1 JDK_MINOR_VER=8 diff --git a/hotspot/make/linux/makefiles/buildtree.make b/hotspot/make/linux/makefiles/buildtree.make index 5bc29368e5e..6af5490da7e 100644 --- a/hotspot/make/linux/makefiles/buildtree.make +++ b/hotspot/make/linux/makefiles/buildtree.make @@ -55,6 +55,7 @@ # The makefiles are split this way so that "make foo" will run faster by not # having to read the dependency files for the vm. +-include $(SPEC) include $(GAMMADIR)/make/scm.make include $(GAMMADIR)/make/altsrc.make @@ -244,6 +245,8 @@ flags.make: $(BUILDTREE_MAKE) ../shared_dirs.lst echo "HOTSPOT_EXTRA_SYSDEFS\$$(HOTSPOT_EXTRA_SYSDEFS) = $(HOTSPOT_EXTRA_SYSDEFS)" && \ echo "SYSDEFS += \$$(HOTSPOT_EXTRA_SYSDEFS)"; \ echo; \ + [ -n "$(SPEC)" ] && \ + echo "include $(SPEC)"; \ echo "include \$$(GAMMADIR)/make/$(OS_FAMILY)/makefiles/$(VARIANT).make"; \ echo "include \$$(GAMMADIR)/make/$(OS_FAMILY)/makefiles/$(COMPILER).make"; \ ) > $@ diff --git a/hotspot/make/linux/makefiles/gcc.make b/hotspot/make/linux/makefiles/gcc.make index 0188ed772d5..d918ef77bdd 100644 --- a/hotspot/make/linux/makefiles/gcc.make +++ b/hotspot/make/linux/makefiles/gcc.make @@ -25,21 +25,26 @@ #------------------------------------------------------------------------ # CC, CXX & AS -# When cross-compiling the ALT_COMPILER_PATH points -# to the cross-compilation toolset -ifdef CROSS_COMPILE_ARCH -CXX = $(ALT_COMPILER_PATH)/g++ -CC = $(ALT_COMPILER_PATH)/gcc -HOSTCXX = g++ -HOSTCC = gcc -else -CXX = g++ -CC = gcc -HOSTCXX = $(CXX) -HOSTCC = $(CC) +# If a SPEC is not set already, then use these defaults. +ifeq ($(SPEC),) + # When cross-compiling the ALT_COMPILER_PATH points + # to the cross-compilation toolset + ifdef CROSS_COMPILE_ARCH + CXX = $(ALT_COMPILER_PATH)/g++ + CC = $(ALT_COMPILER_PATH)/gcc + HOSTCXX = g++ + HOSTCC = gcc + STRIP = $(ALT_COMPILER_PATH)/strip + else + CXX = g++ + CC = gcc + HOSTCXX = $(CXX) + HOSTCC = $(CC) + STRIP = strip + endif + AS = $(CC) -c endif -AS = $(CC) -c # -dumpversion in gcc-2.91 shows "egcs-2.91.66". In later version, it only # prints the numbers (e.g. "2.95", "3.2.1") @@ -261,9 +266,3 @@ endif ifdef MINIMIZE_RAM_USAGE CFLAGS += -DMINIMIZE_RAM_USAGE endif - -ifdef CROSS_COMPILE_ARCH - STRIP = $(ALT_COMPILER_PATH)/strip -else - STRIP = strip -endif diff --git a/hotspot/make/linux/makefiles/sparcWorks.make b/hotspot/make/linux/makefiles/sparcWorks.make index 81de9c33baa..c87f5044096 100644 --- a/hotspot/make/linux/makefiles/sparcWorks.make +++ b/hotspot/make/linux/makefiles/sparcWorks.make @@ -25,12 +25,15 @@ #------------------------------------------------------------------------ # CC, CXX & AS -CXX = CC -CC = cc -AS = $(CC) -c +# If a SPEC is not set already, then use these defaults. +ifeq ($(SPEC),) + CXX = CC + CC = cc + AS = $(CC) -c -HOSTCXX = $(CXX) -HOSTCC = $(CC) + HOSTCXX = $(CXX) + HOSTCC = $(CC) +endif ARCHFLAG = $(ARCHFLAG/$(BUILDARCH)) ARCHFLAG/i486 = -m32 diff --git a/hotspot/make/solaris/makefiles/buildtree.make b/hotspot/make/solaris/makefiles/buildtree.make index 129a4849431..901100fb708 100644 --- a/hotspot/make/solaris/makefiles/buildtree.make +++ b/hotspot/make/solaris/makefiles/buildtree.make @@ -55,6 +55,7 @@ # The makefiles are split this way so that "make foo" will run faster by not # having to read the dependency files for the vm. +-include $(SPEC) include $(GAMMADIR)/make/scm.make include $(GAMMADIR)/make/altsrc.make @@ -237,6 +238,8 @@ flags.make: $(BUILDTREE_MAKE) ../shared_dirs.lst echo "HOTSPOT_EXTRA_SYSDEFS\$$(HOTSPOT_EXTRA_SYSDEFS) = $(HOTSPOT_EXTRA_SYSDEFS)" && \ echo "SYSDEFS += \$$(HOTSPOT_EXTRA_SYSDEFS)"; \ echo; \ + [ -n "$(SPEC)" ] && \ + echo "include $(SPEC)"; \ echo "include \$$(GAMMADIR)/make/$(OS_FAMILY)/makefiles/$(VARIANT).make"; \ echo "include \$$(GAMMADIR)/make/$(OS_FAMILY)/makefiles/$(COMPILER).make"; \ ) > $@ diff --git a/hotspot/make/solaris/makefiles/gcc.make b/hotspot/make/solaris/makefiles/gcc.make index d4c54abd284..4d0db9e7a7a 100644 --- a/hotspot/make/solaris/makefiles/gcc.make +++ b/hotspot/make/solaris/makefiles/gcc.make @@ -25,9 +25,13 @@ #------------------------------------------------------------------------ # CC, CXX & AS -CXX = g++ -CC = gcc -AS = $(CC) -c +# If a SPEC is not set already, then use these defaults. +ifeq ($(SPEC),) + CXX = g++ + CC = gcc + AS = $(CC) -c + MCS = /usr/ccs/bin/mcs +endif Compiler = gcc @@ -193,5 +197,3 @@ DEBUG_CFLAGS += $(DEBUG_CFLAGS/$(BUILDARCH)) ifeq ($(DEBUG_CFLAGS/$(BUILDARCH)),) DEBUG_CFLAGS += -gstabs endif - -MCS = /usr/ccs/bin/mcs diff --git a/hotspot/make/solaris/makefiles/sparcWorks.make b/hotspot/make/solaris/makefiles/sparcWorks.make index 8baf3c1d427..8ef47c56317 100644 --- a/hotspot/make/solaris/makefiles/sparcWorks.make +++ b/hotspot/make/solaris/makefiles/sparcWorks.make @@ -22,18 +22,22 @@ # # -# Compiler-specific flags for sparcworks. +# If a SPEC is not set already, then use these defaults. +ifeq ($(SPEC),) + # Compiler-specific flags for sparcworks. + CC = cc + CXX = CC -# tell make which C and C++ compilers to use -CC = cc -CXX = CC + # Note that this 'as' is an older version of the Sun Studio 'fbe', and will + # use the older style options. The 'fbe' options will match 'cc' and 'CC'. + AS = /usr/ccs/bin/as -# Note that this 'as' is an older version of the Sun Studio 'fbe', and will -# use the older style options. The 'fbe' options will match 'cc' and 'CC'. -AS = /usr/ccs/bin/as + NM = /usr/ccs/bin/nm + NAWK = /bin/nawk -NM = /usr/ccs/bin/nm -NAWK = /bin/nawk + MCS = /usr/ccs/bin/mcs + STRIP = /usr/ccs/bin/strip +endif REORDER_FLAG = -xF @@ -557,9 +561,6 @@ else #LINK_INTO = LIBJVM endif -MCS = /usr/ccs/bin/mcs -STRIP = /usr/ccs/bin/strip - # Solaris platforms collect lots of redundant file-ident lines, # to the point of wasting a significant percentage of file space. # (The text is stored in ELF .comment sections, contributed by diff --git a/hotspot/make/windows/build.make b/hotspot/make/windows/build.make index 8ec004d4903..fff8a8530c7 100644 --- a/hotspot/make/windows/build.make +++ b/hotspot/make/windows/build.make @@ -297,6 +297,10 @@ $(variantDir)\local.make: checks @ echo BUILDARCH=$(BUILDARCH) >> $@ @ echo Platform_arch=$(Platform_arch) >> $@ @ echo Platform_arch_model=$(Platform_arch_model) >> $@ + @ echo CXX=$(CXX) >> $@ + @ echo LD=$(LD) >> $@ + @ echo MT=$(MT) >> $@ + @ echo RC=$(RC) >> $@ @ sh $(WorkSpace)/make/windows/get_msc_ver.sh >> $@ checks: checkVariant checkWorkSpace checkSA diff --git a/hotspot/make/windows/makefiles/compile.make b/hotspot/make/windows/makefiles/compile.make index 1c9855c15dc..e1848a4ac51 100644 --- a/hotspot/make/windows/makefiles/compile.make +++ b/hotspot/make/windows/makefiles/compile.make @@ -23,7 +23,9 @@ # # Generic compiler settings +!if "x$(CXX)" == "x" CXX=cl.exe +!endif # CXX Flags: (these vary slightly from VC6->VS2003->VS2005 compilers) # /nologo Supress copyright message at every cl.exe startup @@ -183,8 +185,10 @@ BUFFEROVERFLOWLIB = bufferoverflowU.lib LD_FLAGS = /manifest $(LD_FLAGS) $(BUFFEROVERFLOWLIB) # Manifest Tool - used in VS2005 and later to adjust manifests stored # as resources inside build artifacts. +!if "x$(MT)" == "x" MT=mt.exe !endif +!endif !if "$(COMPILER_NAME)" == "VS2008" PRODUCT_OPT_OPTION = /O2 /Oy- @@ -194,8 +198,10 @@ GX_OPTION = /EHsc LD_FLAGS = /manifest $(LD_FLAGS) # Manifest Tool - used in VS2005 and later to adjust manifests stored # as resources inside build artifacts. +!if "x$(MT)" == "x" MT=mt.exe !endif +!endif !if "$(COMPILER_NAME)" == "VS2010" PRODUCT_OPT_OPTION = /O2 /Oy- @@ -205,7 +211,9 @@ GX_OPTION = /EHsc LD_FLAGS = /manifest $(LD_FLAGS) # Manifest Tool - used in VS2005 and later to adjust manifests stored # as resources inside build artifacts. +!if "x$(MT)" == "x" MT=mt.exe +!endif !if "$(BUILDARCH)" == "i486" LD_FLAGS = /SAFESEH $(LD_FLAGS) !endif @@ -225,7 +233,9 @@ FASTDEBUG_OPT_OPTION = $(DEBUG_OPT_OPTION) !endif # Generic linker settings +!if "x$(LD)" == "x" LD=link.exe +!endif LD_FLAGS= $(LD_FLAGS) kernel32.lib user32.lib gdi32.lib winspool.lib \ comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib \ uuid.lib Wsock32.lib winmm.lib /nologo /machine:$(MACHINE) /opt:REF \ @@ -237,7 +247,9 @@ LD_FLAGS= $(LD_FLAGS) psapi.lib !endif # Resource compiler settings +!if "x$(RC)" == "x" RC=rc.exe +!endif RC_FLAGS=/D "HS_VER=$(HS_VER)" \ /D "HS_DOTVER=$(HS_DOTVER)" \ /D "HS_BUILD_ID=$(HS_BUILD_ID)" \ diff --git a/hotspot/make/windows/makefiles/defs.make b/hotspot/make/windows/makefiles/defs.make index c1be7d2c863..993799e37b0 100644 --- a/hotspot/make/windows/makefiles/defs.make +++ b/hotspot/make/windows/makefiles/defs.make @@ -202,3 +202,19 @@ ifeq ($(BUILD_WIN_SA), 1) # Must pass this down to nmake. MAKE_ARGS += BUILD_WIN_SA=1 endif + +# Propagate compiler and tools paths from configure to nmake. +# Need to make sure they contain \\ and not /. +ifneq ($(SPEC),) + ifeq ($(USING_CYGWIN), true) + MAKE_ARGS += CXX="$(subst /,\\,$(shell /bin/cygpath -s -m -a $(CXX)))" + MAKE_ARGS += LD="$(subst /,\\,$(shell /bin/cygpath -s -m -a $(LD)))" + MAKE_ARGS += RC="$(subst /,\\,$(shell /bin/cygpath -s -m -a $(RC)))" + MAKE_ARGS += MT="$(subst /,\\,$(shell /bin/cygpath -s -m -a $(MT)))" + else + MAKE_ARGS += CXX="$(subst /,\\,$(CXX))" + MAKE_ARGS += LD="$(subst /,\\,$(LD))" + MAKE_ARGS += RC="$(subst /,\\,$(RC))" + MAKE_ARGS += MT="$(subst /,\\,$(MT))" + endif +endif diff --git a/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp b/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp index 5f2cf3886ca..30df6087d23 100644 --- a/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp +++ b/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp @@ -47,6 +47,12 @@ int StubAssembler::call_RT(Register oop_result1, Register oop_result2, address e assert(!(oop_result1->is_valid() || oop_result2->is_valid()) || oop_result1 != oop_result2, "registers must be different"); assert(oop_result1 != thread && oop_result2 != thread, "registers must be different"); assert(args_size >= 0, "illegal args_size"); + bool align_stack = false; +#ifdef _LP64 + // At a method handle call, the stack may not be properly aligned + // when returning with an exception. + align_stack = (stub_id() == Runtime1::handle_exception_from_callee_id); +#endif #ifdef _LP64 mov(c_rarg0, thread); @@ -59,11 +65,21 @@ int StubAssembler::call_RT(Register oop_result1, Register oop_result2, address e push(thread); #endif // _LP64 - set_last_Java_frame(thread, noreg, rbp, NULL); + int call_offset; + if (!align_stack) { + set_last_Java_frame(thread, noreg, rbp, NULL); + } else { + address the_pc = pc(); + call_offset = offset(); + set_last_Java_frame(thread, noreg, rbp, the_pc); + andptr(rsp, -(StackAlignmentInBytes)); // Align stack + } // do the call call(RuntimeAddress(entry)); - int call_offset = offset(); + if (!align_stack) { + call_offset = offset(); + } // verify callee-saved register #ifdef ASSERT guarantee(thread != rax, "change this code"); @@ -78,7 +94,7 @@ int StubAssembler::call_RT(Register oop_result1, Register oop_result2, address e } pop(rax); #endif - reset_last_Java_frame(thread, true, false); + reset_last_Java_frame(thread, true, align_stack); // discard thread and arguments NOT_LP64(addptr(rsp, num_rt_args()*BytesPerWord)); diff --git a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp index b7af4544d1f..68a23939df4 100644 --- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp @@ -1181,14 +1181,13 @@ static void save_or_restore_arguments(MacroAssembler* masm, BasicType* in_sig_bt) { // if map is non-NULL then the code should store the values, // otherwise it should load them. - int handle_index = 0; + int slot = arg_save_area; // Save down double word first for ( int i = 0; i < total_in_args; i++) { if (in_regs[i].first()->is_XMMRegister() && in_sig_bt[i] == T_DOUBLE) { - int slot = handle_index * VMRegImpl::slots_per_word + arg_save_area; int offset = slot * VMRegImpl::stack_slot_size; - handle_index += 2; - assert(handle_index <= stack_slots, "overflow"); + slot += VMRegImpl::slots_per_word; + assert(slot <= stack_slots, "overflow"); if (map != NULL) { __ movdbl(Address(rsp, offset), in_regs[i].first()->as_XMMRegister()); } else { @@ -1197,10 +1196,7 @@ static void save_or_restore_arguments(MacroAssembler* masm, } if (in_regs[i].first()->is_Register() && (in_sig_bt[i] == T_LONG || in_sig_bt[i] == T_ARRAY)) { - int slot = handle_index * VMRegImpl::slots_per_word + arg_save_area; int offset = slot * VMRegImpl::stack_slot_size; - handle_index += 2; - assert(handle_index <= stack_slots, "overflow"); if (map != NULL) { __ movq(Address(rsp, offset), in_regs[i].first()->as_Register()); if (in_sig_bt[i] == T_ARRAY) { @@ -1209,14 +1205,15 @@ static void save_or_restore_arguments(MacroAssembler* masm, } else { __ movq(in_regs[i].first()->as_Register(), Address(rsp, offset)); } + slot += VMRegImpl::slots_per_word; } } // Save or restore single word registers for ( int i = 0; i < total_in_args; i++) { if (in_regs[i].first()->is_Register()) { - int slot = handle_index++ * VMRegImpl::slots_per_word + arg_save_area; int offset = slot * VMRegImpl::stack_slot_size; - assert(handle_index <= stack_slots, "overflow"); + slot++; + assert(slot <= stack_slots, "overflow"); // Value is in an input register pass we must flush it to the stack const Register reg = in_regs[i].first()->as_Register(); @@ -1241,9 +1238,9 @@ static void save_or_restore_arguments(MacroAssembler* masm, } } else if (in_regs[i].first()->is_XMMRegister()) { if (in_sig_bt[i] == T_FLOAT) { - int slot = handle_index++ * VMRegImpl::slots_per_word + arg_save_area; int offset = slot * VMRegImpl::stack_slot_size; - assert(handle_index <= stack_slots, "overflow"); + slot++; + assert(slot <= stack_slots, "overflow"); if (map != NULL) { __ movflt(Address(rsp, offset), in_regs[i].first()->as_XMMRegister()); } else { @@ -1368,6 +1365,174 @@ static void unpack_array_argument(MacroAssembler* masm, VMRegPair reg, BasicType __ bind(done); } + +class ComputeMoveOrder: public StackObj { + class MoveOperation: public ResourceObj { + friend class ComputeMoveOrder; + private: + VMRegPair _src; + VMRegPair _dst; + int _src_index; + int _dst_index; + bool _processed; + MoveOperation* _next; + MoveOperation* _prev; + + static int get_id(VMRegPair r) { + return r.first()->value(); + } + + public: + MoveOperation(int src_index, VMRegPair src, int dst_index, VMRegPair dst): + _src(src) + , _src_index(src_index) + , _dst(dst) + , _dst_index(dst_index) + , _next(NULL) + , _prev(NULL) + , _processed(false) { + } + + VMRegPair src() const { return _src; } + int src_id() const { return get_id(src()); } + int src_index() const { return _src_index; } + VMRegPair dst() const { return _dst; } + void set_dst(int i, VMRegPair dst) { _dst_index = i, _dst = dst; } + int dst_index() const { return _dst_index; } + int dst_id() const { return get_id(dst()); } + MoveOperation* next() const { return _next; } + MoveOperation* prev() const { return _prev; } + void set_processed() { _processed = true; } + bool is_processed() const { return _processed; } + + // insert + void break_cycle(VMRegPair temp_register) { + // create a new store following the last store + // to move from the temp_register to the original + MoveOperation* new_store = new MoveOperation(-1, temp_register, dst_index(), dst()); + + // break the cycle of links and insert new_store at the end + // break the reverse link. + MoveOperation* p = prev(); + assert(p->next() == this, "must be"); + _prev = NULL; + p->_next = new_store; + new_store->_prev = p; + + // change the original store to save it's value in the temp. + set_dst(-1, temp_register); + } + + void link(GrowableArray& killer) { + // link this store in front the store that it depends on + MoveOperation* n = killer.at_grow(src_id(), NULL); + if (n != NULL) { + assert(_next == NULL && n->_prev == NULL, "shouldn't have been set yet"); + _next = n; + n->_prev = this; + } + } + }; + + private: + GrowableArray edges; + + public: + ComputeMoveOrder(int total_in_args, VMRegPair* in_regs, int total_c_args, VMRegPair* out_regs, + BasicType* in_sig_bt, GrowableArray& arg_order, VMRegPair tmp_vmreg) { + // Move operations where the dest is the stack can all be + // scheduled first since they can't interfere with the other moves. + for (int i = total_in_args - 1, c_arg = total_c_args - 1; i >= 0; i--, c_arg--) { + if (in_sig_bt[i] == T_ARRAY) { + c_arg--; + if (out_regs[c_arg].first()->is_stack() && + out_regs[c_arg + 1].first()->is_stack()) { + arg_order.push(i); + arg_order.push(c_arg); + } else { + if (out_regs[c_arg].first()->is_stack() || + in_regs[i].first() == out_regs[c_arg].first()) { + add_edge(i, in_regs[i].first(), c_arg, out_regs[c_arg + 1]); + } else { + add_edge(i, in_regs[i].first(), c_arg, out_regs[c_arg]); + } + } + } else if (in_sig_bt[i] == T_VOID) { + arg_order.push(i); + arg_order.push(c_arg); + } else { + if (out_regs[c_arg].first()->is_stack() || + in_regs[i].first() == out_regs[c_arg].first()) { + arg_order.push(i); + arg_order.push(c_arg); + } else { + add_edge(i, in_regs[i].first(), c_arg, out_regs[c_arg]); + } + } + } + // Break any cycles in the register moves and emit the in the + // proper order. + GrowableArray* stores = get_store_order(tmp_vmreg); + for (int i = 0; i < stores->length(); i++) { + arg_order.push(stores->at(i)->src_index()); + arg_order.push(stores->at(i)->dst_index()); + } + } + + // Collected all the move operations + void add_edge(int src_index, VMRegPair src, int dst_index, VMRegPair dst) { + if (src.first() == dst.first()) return; + edges.append(new MoveOperation(src_index, src, dst_index, dst)); + } + + // Walk the edges breaking cycles between moves. The result list + // can be walked in order to produce the proper set of loads + GrowableArray* get_store_order(VMRegPair temp_register) { + // Record which moves kill which values + GrowableArray killer; + for (int i = 0; i < edges.length(); i++) { + MoveOperation* s = edges.at(i); + assert(killer.at_grow(s->dst_id(), NULL) == NULL, "only one killer"); + killer.at_put_grow(s->dst_id(), s, NULL); + } + assert(killer.at_grow(MoveOperation::get_id(temp_register), NULL) == NULL, + "make sure temp isn't in the registers that are killed"); + + // create links between loads and stores + for (int i = 0; i < edges.length(); i++) { + edges.at(i)->link(killer); + } + + // at this point, all the move operations are chained together + // in a doubly linked list. Processing it backwards finds + // the beginning of the chain, forwards finds the end. If there's + // a cycle it can be broken at any point, so pick an edge and walk + // backward until the list ends or we end where we started. + GrowableArray* stores = new GrowableArray(); + for (int e = 0; e < edges.length(); e++) { + MoveOperation* s = edges.at(e); + if (!s->is_processed()) { + MoveOperation* start = s; + // search for the beginning of the chain or cycle + while (start->prev() != NULL && start->prev() != s) { + start = start->prev(); + } + if (start->prev() == s) { + start->break_cycle(temp_register); + } + // walk the chain forward inserting to store list + while (start != NULL) { + stores->append(start); + start->set_processed(); + start = start->next(); + } + } + } + return stores; + } +}; + + // --------------------------------------------------------------------------- // Generate a native wrapper for a given method. The method takes arguments // in the Java compiled code convention, marshals them to the native @@ -1488,12 +1653,12 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, if (in_regs[i].first()->is_Register()) { const Register reg = in_regs[i].first()->as_Register(); switch (in_sig_bt[i]) { - case T_ARRAY: case T_BOOLEAN: case T_BYTE: case T_SHORT: case T_CHAR: case T_INT: single_slots++; break; + case T_ARRAY: case T_LONG: double_slots++; break; default: ShouldNotReachHere(); } @@ -1690,36 +1855,43 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, #endif /* ASSERT */ - if (is_critical_native) { - // The mapping of Java and C arguments passed in registers are - // rotated by one, which helps when passing arguments to regular - // Java method but for critical natives that creates a cycle which - // can cause arguments to be killed before they are used. Break - // the cycle by moving the first argument into a temporary - // register. - for (int i = 0; i < total_c_args; i++) { - if (in_regs[i].first()->is_Register() && - in_regs[i].first()->as_Register() == rdi) { - __ mov(rbx, rdi); - in_regs[i].set1(rbx->as_VMReg()); - } - } - } - // This may iterate in two different directions depending on the // kind of native it is. The reason is that for regular JNI natives // the incoming and outgoing registers are offset upwards and for // critical natives they are offset down. - int c_arg = total_c_args - 1; - int stride = -1; - int init = total_in_args - 1; - if (is_critical_native) { - // stride forwards - c_arg = 0; - stride = 1; - init = 0; + GrowableArray arg_order(2 * total_in_args); + VMRegPair tmp_vmreg; + tmp_vmreg.set1(rbx->as_VMReg()); + + if (!is_critical_native) { + for (int i = total_in_args - 1, c_arg = total_c_args - 1; i >= 0; i--, c_arg--) { + arg_order.push(i); + arg_order.push(c_arg); + } + } else { + // Compute a valid move order, using tmp_vmreg to break any cycles + ComputeMoveOrder cmo(total_in_args, in_regs, total_c_args, out_regs, in_sig_bt, arg_order, tmp_vmreg); } - for (int i = init, count = 0; count < total_in_args; i += stride, c_arg += stride, count++ ) { + + int temploc = -1; + for (int ai = 0; ai < arg_order.length(); ai += 2) { + int i = arg_order.at(ai); + int c_arg = arg_order.at(ai + 1); + __ block_comment(err_msg("move %d -> %d", i, c_arg)); + if (c_arg == -1) { + assert(is_critical_native, "should only be required for critical natives"); + // This arg needs to be moved to a temporary + __ mov(tmp_vmreg.first()->as_Register(), in_regs[i].first()->as_Register()); + in_regs[i] = tmp_vmreg; + temploc = i; + continue; + } else if (i == -1) { + assert(is_critical_native, "should only be required for critical natives"); + // Read from the temporary location + assert(temploc != -1, "must be valid"); + i = temploc; + temploc = -1; + } #ifdef ASSERT if (in_regs[i].first()->is_Register()) { assert(!reg_destroyed[in_regs[i].first()->as_Register()->encoding()], "destroyed reg!"); @@ -1779,7 +1951,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, // point c_arg at the first arg that is already loaded in case we // need to spill before we call out - c_arg++; + int c_arg = total_c_args - total_in_args; // Pre-load a static method's oop into r14. Used both by locking code and // the normal JNI call code. @@ -3620,8 +3792,12 @@ void OptoRuntime::generate_exception_blob() { // // address OptoRuntime::handle_exception_C(JavaThread* thread) - __ set_last_Java_frame(noreg, noreg, NULL); + // At a method handle call, the stack may not be properly aligned + // when returning with an exception. + address the_pc = __ pc(); + __ set_last_Java_frame(noreg, noreg, the_pc); __ mov(c_rarg0, r15_thread); + __ andptr(rsp, -(StackAlignmentInBytes)); // Align stack __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, OptoRuntime::handle_exception_C))); // Set an oopmap for the call site. This oopmap will only be used if we @@ -3632,9 +3808,9 @@ void OptoRuntime::generate_exception_blob() { OopMapSet* oop_maps = new OopMapSet(); - oop_maps->add_gc_map( __ pc()-start, new OopMap(SimpleRuntimeFrame::framesize, 0)); + oop_maps->add_gc_map(the_pc - start, new OopMap(SimpleRuntimeFrame::framesize, 0)); - __ reset_last_Java_frame(false, false); + __ reset_last_Java_frame(false, true); // Restore callee-saved registers diff --git a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp index d68bdac6db8..9d9472200e3 100644 --- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp @@ -710,6 +710,21 @@ class StubGenerator: public StubCodeGenerator { return start; } + // Support for intptr_t get_previous_sp() + // + // This routine is used to find the previous stack pointer for the + // caller. + address generate_get_previous_sp() { + StubCodeMark mark(this, "StubRoutines", "get_previous_sp"); + address start = __ pc(); + + __ movptr(rax, rsp); + __ addptr(rax, 8); // return address is at the top of the stack. + __ ret(0); + + return start; + } + //---------------------------------------------------------------------------------------------------- // Support for void verify_mxcsr() // @@ -3060,6 +3075,7 @@ class StubGenerator: public StubCodeGenerator { // platform dependent StubRoutines::x86::_get_previous_fp_entry = generate_get_previous_fp(); + StubRoutines::x86::_get_previous_sp_entry = generate_get_previous_sp(); StubRoutines::x86::_verify_mxcsr_entry = generate_verify_mxcsr(); diff --git a/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.cpp b/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.cpp index 182872b88e7..782dc906399 100644 --- a/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.cpp @@ -43,6 +43,7 @@ // a description of how to extend it, see the stubRoutines.hpp file. address StubRoutines::x86::_get_previous_fp_entry = NULL; +address StubRoutines::x86::_get_previous_sp_entry = NULL; address StubRoutines::x86::_verify_mxcsr_entry = NULL; diff --git a/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.hpp b/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.hpp index 3d2a4fb9a33..7737c4eee6e 100644 --- a/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.hpp +++ b/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.hpp @@ -41,6 +41,7 @@ class x86 { private: static address _get_previous_fp_entry; + static address _get_previous_sp_entry; static address _verify_mxcsr_entry; static address _f2i_fixup; @@ -61,6 +62,11 @@ class x86 { return _get_previous_fp_entry; } + static address get_previous_sp_entry() + { + return _get_previous_sp_entry; + } + static address verify_mxcsr_entry() { return _verify_mxcsr_entry; diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp index 72f3fd07a6c..6a33c0e8046 100644 --- a/hotspot/src/os/linux/vm/os_linux.cpp +++ b/hotspot/src/os/linux/vm/os_linux.cpp @@ -4690,14 +4690,12 @@ char* os::map_memory(int fd, const char* file_name, size_t file_offset, char *addr, size_t bytes, bool read_only, bool allow_exec) { int prot; - int flags; + int flags = MAP_PRIVATE; if (read_only) { prot = PROT_READ; - flags = MAP_SHARED; } else { prot = PROT_READ | PROT_WRITE; - flags = MAP_PRIVATE; } if (allow_exec) { diff --git a/hotspot/src/os/solaris/vm/os_solaris.cpp b/hotspot/src/os/solaris/vm/os_solaris.cpp index c47d374333e..31bd41862a6 100644 --- a/hotspot/src/os/solaris/vm/os_solaris.cpp +++ b/hotspot/src/os/solaris/vm/os_solaris.cpp @@ -1013,15 +1013,6 @@ extern "C" void breakpoint() { // use debugger to set breakpoint here } -// Returns an estimate of the current stack pointer. Result must be guaranteed to -// point into the calling threads stack, and be no lower than the current stack -// pointer. -address os::current_stack_pointer() { - volatile int dummy; - address sp = (address)&dummy + 8; // %%%% need to confirm if this is right - return sp; -} - static thread_t main_thread; // Thread start routine for all new Java threads diff --git a/hotspot/src/os/windows/vm/os_windows.cpp b/hotspot/src/os/windows/vm/os_windows.cpp index 970aab7477b..de38c6c12da 100644 --- a/hotspot/src/os/windows/vm/os_windows.cpp +++ b/hotspot/src/os/windows/vm/os_windows.cpp @@ -324,16 +324,6 @@ extern "C" void breakpoint() { os::breakpoint(); } -// Returns an estimate of the current stack pointer. Result must be guaranteed -// to point into the calling threads stack, and be no lower than the current -// stack pointer. - -address os::current_stack_pointer() { - int dummy; - address sp = (address)&dummy; - return sp; -} - // os::current_stack_base() // // Returns the base of the stack, which is the stack's diff --git a/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp b/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp index 06ba580753a..12d6871ca04 100644 --- a/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp +++ b/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp @@ -1126,3 +1126,8 @@ void os::setup_fpu() { : "r" (fpu_cntrl) : "memory"); #endif // !AMD64 } + +#ifndef PRODUCT +void os::verify_stack_alignment() { +} +#endif diff --git a/hotspot/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp b/hotspot/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp index ff5b32dbf26..4bb5a8abb24 100644 --- a/hotspot/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp +++ b/hotspot/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp @@ -562,3 +562,8 @@ extern "C" { } }; #endif // !_LP64 + +#ifndef PRODUCT +void os::verify_stack_alignment() { +} +#endif diff --git a/hotspot/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp b/hotspot/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp index 62131ee6f10..11c90e522fc 100644 --- a/hotspot/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp +++ b/hotspot/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp @@ -756,3 +756,8 @@ size_t os::Linux::default_guard_size(os::ThreadType thr_type) { // guard page, only enable glibc guard page for non-Java threads. return (thr_type == java_thread ? 0 : page_size()); } + +#ifndef PRODUCT +void os::verify_stack_alignment() { +} +#endif diff --git a/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp index ba484b9fde5..93bb1f45919 100644 --- a/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp +++ b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp @@ -862,3 +862,11 @@ void os::setup_fpu() { : "r" (fpu_cntrl) : "memory"); #endif // !AMD64 } + +#ifndef PRODUCT +void os::verify_stack_alignment() { +#ifdef AMD64 + assert(((intptr_t)os::current_stack_pointer() & (StackAlignmentInBytes-1)) == 0, "incorrect stack alignment"); +#endif +} +#endif diff --git a/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp b/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp index 32c2d0a5191..203090ce079 100644 --- a/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp +++ b/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp @@ -506,3 +506,8 @@ extern "C" { } }; #endif // !_LP64 + +#ifndef PRODUCT +void os::verify_stack_alignment() { +} +#endif diff --git a/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp b/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp index 971f600fe30..752daf7bf67 100644 --- a/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp +++ b/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp @@ -251,6 +251,15 @@ frame os::get_sender_for_C_frame(frame* fr) { return frame(fr->sender_sp(), frame::unpatchable, fr->sender_pc()); } +// Returns an estimate of the current stack pointer. Result must be guaranteed to +// point into the calling threads stack, and be no lower than the current stack +// pointer. +address os::current_stack_pointer() { + volatile int dummy; + address sp = (address)&dummy + 8; // %%%% need to confirm if this is right + return sp; +} + frame os::current_frame() { intptr_t* sp = StubRoutines::Sparc::flush_callers_register_windows_func()(); frame myframe(sp, frame::unpatchable, @@ -815,3 +824,8 @@ add_func_t* os::atomic_add_func = os::atomic_add_bootstrap; __asm__ __volatile__ ("wr %%g0, 0, %%fprs \n\t" : : :); } #endif //defined(__sparc) && defined(COMPILER2) + +#ifndef PRODUCT +void os::verify_stack_alignment() { +} +#endif diff --git a/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp b/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp index 78e93ea6652..ec047c16b58 100644 --- a/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp +++ b/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp @@ -237,6 +237,12 @@ frame os::get_sender_for_C_frame(frame* fr) { return frame(fr->sender_sp(), fr->link(), fr->sender_pc()); } +extern "C" intptr_t *_get_current_sp(); // in .il file + +address os::current_stack_pointer() { + return (address)_get_current_sp(); +} + extern "C" intptr_t *_get_current_fp(); // in .il file frame os::current_frame() { @@ -954,3 +960,11 @@ void os::setup_fpu() { _solaris_raw_setup_fpu(fpu_cntrl); } #endif // AMD64 + +#ifndef PRODUCT +void os::verify_stack_alignment() { +#ifdef AMD64 + assert(((intptr_t)os::current_stack_pointer() & (StackAlignmentInBytes-1)) == 0, "incorrect stack alignment"); +#endif +} +#endif diff --git a/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_32.il b/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_32.il index b635a8292e6..9b0f07da315 100644 --- a/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_32.il +++ b/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_32.il @@ -37,6 +37,12 @@ movl %gs:0, %eax .end + // Get current sp + .inline _get_current_sp,0 + .volatile + movl %esp, %eax + .end + // Get current fp .inline _get_current_fp,0 .volatile diff --git a/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_64.il b/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_64.il index fb7946b8c5c..89809bc54dd 100644 --- a/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_64.il +++ b/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_64.il @@ -30,6 +30,12 @@ movq %fs:0, %rax .end + // Get current sp + .inline _get_current_sp,0 + .volatile + movq %rsp, %rax + .end + // Get current fp .inline _get_current_fp,0 .volatile diff --git a/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp b/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp index 960ceab665a..52fe243ee0e 100644 --- a/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp +++ b/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp @@ -370,6 +370,26 @@ frame os::get_sender_for_C_frame(frame* fr) { return frame(fr->sender_sp(), fr->link(), fr->sender_pc()); } +#ifndef AMD64 +// Returns an estimate of the current stack pointer. Result must be guaranteed +// to point into the calling threads stack, and be no lower than the current +// stack pointer. +address os::current_stack_pointer() { + int dummy; + address sp = (address)&dummy; + return sp; +} +#else +// Returns the current stack pointer. Accurate value needed for +// os::verify_stack_alignment(). +address os::current_stack_pointer() { + typedef address get_sp_func(); + get_sp_func* func = CAST_TO_FN_PTR(get_sp_func*, + StubRoutines::x86::get_previous_sp_entry()); + return (*func)(); +} +#endif + #ifndef AMD64 intptr_t* _get_previous_fp() { @@ -546,3 +566,11 @@ void os::setup_fpu() { __asm fldcw fpu_cntrl_word; #endif // !AMD64 } + +#ifndef PRODUCT +void os::verify_stack_alignment() { +#ifdef AMD64 + assert(((intptr_t)os::current_stack_pointer() & (StackAlignmentInBytes-1)) == 0, "incorrect stack alignment"); +#endif +} +#endif diff --git a/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/Compilation.java b/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/Compilation.java index 73e59566e1f..861fe443753 100644 --- a/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/Compilation.java +++ b/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/Compilation.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,6 +33,7 @@ public class Compilation implements LogEvent { private boolean osr; private Method method; private CallSite call = new CallSite(); + private CallSite lateInlineCall = new CallSite(); private int osrBci; private String icount; private String bcount; @@ -80,6 +81,13 @@ public class Compilation implements LogEvent { sb.append(site); sb.append("\n"); } + if (getLateInlineCall().getCalls() != null) { + sb.append("late inline:\n"); + for (CallSite site : getLateInlineCall().getCalls()) { + sb.append(site); + sb.append("\n"); + } + } return sb.toString(); } @@ -115,6 +123,12 @@ public class Compilation implements LogEvent { site.print(stream, indent + 2); } } + if (printInlining && lateInlineCall.getCalls() != null) { + stream.println("late inline:"); + for (CallSite site : lateInlineCall.getCalls()) { + site.print(stream, indent + 2); + } + } } } @@ -215,7 +229,11 @@ public class Compilation implements LogEvent { } public void setMethod(Method method) { - this.method = method; + // Don't change method if it is already set to avoid changing + // it by post parse inlining info. + if (getMethod() == null) { + this.method = method; + } } public CallSite getCall() { @@ -226,6 +244,10 @@ public class Compilation implements LogEvent { this.call = call; } + public CallSite getLateInlineCall() { + return lateInlineCall; + } + public double getElapsedTime() { return end - start; } diff --git a/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogParser.java b/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogParser.java index d864db0ff71..dc0b7ab3429 100644 --- a/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogParser.java +++ b/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogParser.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -146,6 +146,7 @@ public class LogParser extends DefaultHandler implements ErrorHandler, Constants private CallSite site; private Stack phaseStack = new Stack(); private UncommonTrapEvent currentTrap; + private Stack late_inline_scope; long parseLong(String l) { try { @@ -302,6 +303,7 @@ public class LogParser extends DefaultHandler implements ErrorHandler, Constants } events.add(compile); compiles.put(makeId(atts), compile); + site = compile.getCall(); } else if (qname.equals("type")) { type(search(atts, "id"), search(atts, "name")); } else if (qname.equals("bc")) { @@ -360,12 +362,22 @@ public class LogParser extends DefaultHandler implements ErrorHandler, Constants // uncommon trap inserted during parsing. // ignore for now } + } else if (qname.equals("late_inline")) { + late_inline_scope = new Stack(); + site = new CallSite(-999, method(search(atts, "method"))); + late_inline_scope.push(site); } else if (qname.equals("jvms")) { // if (currentTrap != null) { currentTrap.addJVMS(atts.getValue("method"), Integer.parseInt(atts.getValue("bci"))); + } else if (late_inline_scope != null) { + bci = Integer.parseInt(search(atts, "bci")); + site = new CallSite(bci, method(search(atts, "method"))); + late_inline_scope.push(site); } else { - // Ignore and + // Ignore , + // , + // } } else if (qname.equals("nmethod")) { String id = makeId(atts); @@ -379,7 +391,7 @@ public class LogParser extends DefaultHandler implements ErrorHandler, Constants Method m = method(search(atts, "method")); if (scopes.size() == 0) { compile.setMethod(m); - scopes.push(compile.getCall()); + scopes.push(site); } else { if (site.getMethod() == m) { scopes.push(site); @@ -393,7 +405,7 @@ public class LogParser extends DefaultHandler implements ErrorHandler, Constants } } else if (qname.equals("parse_done")) { CallSite call = scopes.pop(); - call.setEndNodes(Integer.parseInt(search(atts, "nodes"))); + call.setEndNodes(Integer.parseInt(search(atts, "nodes", "1"))); call.setTimeStamp(Double.parseDouble(search(atts, "stamp"))); scopes.push(call); } @@ -408,6 +420,43 @@ public class LogParser extends DefaultHandler implements ErrorHandler, Constants scopes.pop(); } else if (qname.equals("uncommon_trap")) { currentTrap = null; + } else if (qname.equals("late_inline")) { + // Populate late inlining info. + + // late_inline scopes are specified in reverse order: + // compiled method should be on top of stack. + CallSite caller = late_inline_scope.pop(); + Method m = compile.getMethod(); + if (m != caller.getMethod()) { + System.out.println(m); + System.out.println(caller.getMethod() + " bci: " + bci); + throw new InternalError("call site and late_inline info don't match"); + } + + // late_inline contains caller+bci info, convert it + // to bci+callee info used by LogCompilation. + site = compile.getLateInlineCall(); + do { + bci = caller.getBci(); + // Next inlined call. + caller = late_inline_scope.pop(); + CallSite callee = new CallSite(bci, caller.getMethod()); + site.add(callee); + site = callee; + } while (!late_inline_scope.empty()); + + if (caller.getBci() != -999) { + System.out.println(caller.getMethod()); + throw new InternalError("broken late_inline info"); + } + if (site.getMethod() != caller.getMethod()) { + System.out.println(site.getMethod()); + System.out.println(caller.getMethod()); + throw new InternalError("call site and late_inline info don't match"); + } + // late_inline is followed by parse with scopes.size() == 0, + // 'site' will be pushed to scopes. + late_inline_scope = null; } else if (qname.equals("task")) { types.clear(); methods.clear(); diff --git a/hotspot/src/share/vm/c1/c1_LinearScan.cpp b/hotspot/src/share/vm/c1/c1_LinearScan.cpp index aaae71d46cb..fede09fe8a8 100644 --- a/hotspot/src/share/vm/c1/c1_LinearScan.cpp +++ b/hotspot/src/share/vm/c1/c1_LinearScan.cpp @@ -1884,7 +1884,7 @@ void LinearScan::resolve_exception_entry(BlockBegin* block, MoveResolver &move_r if (move_resolver.has_mappings()) { // insert moves after first instruction - move_resolver.set_insert_position(block->lir(), 1); + move_resolver.set_insert_position(block->lir(), 0); move_resolver.resolve_and_append_moves(); } } diff --git a/hotspot/src/share/vm/classfile/vmSymbols.hpp b/hotspot/src/share/vm/classfile/vmSymbols.hpp index d6ed1def52c..92c06342dad 100644 --- a/hotspot/src/share/vm/classfile/vmSymbols.hpp +++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -509,6 +509,9 @@ template(clear_name, "clear") \ template(trigger_method_signature, "(ILjava/lang/management/MemoryUsage;)V") \ template(startAgent_name, "startAgent") \ + template(startRemoteAgent_name, "startRemoteManagementAgent") \ + template(startLocalAgent_name, "startLocalManagementAgent") \ + template(stopRemoteAgent_name, "stopRemoteManagementAgent") \ template(java_lang_management_ThreadInfo_constructor_signature, "(Ljava/lang/Thread;ILjava/lang/Object;Ljava/lang/Thread;JJJJ[Ljava/lang/StackTraceElement;)V") \ template(java_lang_management_ThreadInfo_with_locks_constructor_signature, "(Ljava/lang/Thread;ILjava/lang/Object;Ljava/lang/Thread;JJJJ[Ljava/lang/StackTraceElement;[Ljava/lang/Object;[I[Ljava/lang/Object;)V") \ template(long_long_long_long_void_signature, "(JJJJ)V") \ diff --git a/hotspot/src/share/vm/oops/cpCacheOop.cpp b/hotspot/src/share/vm/oops/cpCacheOop.cpp index 678bc13272e..8ebc9967899 100644 --- a/hotspot/src/share/vm/oops/cpCacheOop.cpp +++ b/hotspot/src/share/vm/oops/cpCacheOop.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -504,17 +504,17 @@ bool ConstantPoolCacheEntry::is_interesting_method_entry(klassOop k) { void ConstantPoolCacheEntry::print(outputStream* st, int index) const { // print separator - if (index == 0) tty->print_cr(" -------------"); + if (index == 0) st->print_cr(" -------------"); // print entry - tty->print("%3d ("PTR_FORMAT") ", index, (intptr_t)this); + st->print("%3d ("PTR_FORMAT") ", index, (intptr_t)this); if (is_secondary_entry()) - tty->print_cr("[%5d|secondary]", main_entry_index()); + st->print_cr("[%5d|secondary]", main_entry_index()); else - tty->print_cr("[%02x|%02x|%5d]", bytecode_2(), bytecode_1(), constant_pool_index()); - tty->print_cr(" [ "PTR_FORMAT"]", (intptr_t)(oop)_f1); - tty->print_cr(" [ "PTR_FORMAT"]", (intptr_t)_f2); - tty->print_cr(" [ "PTR_FORMAT"]", (intptr_t)_flags); - tty->print_cr(" -------------"); + st->print_cr("[%02x|%02x|%5d]", bytecode_2(), bytecode_1(), constant_pool_index()); + st->print_cr(" [ "PTR_FORMAT"]", (intptr_t)(oop)_f1); + st->print_cr(" [ "PTR_FORMAT"]", (intptr_t)_f2); + st->print_cr(" [ "PTR_FORMAT"]", (intptr_t)_flags); + st->print_cr(" -------------"); } void ConstantPoolCacheEntry::verify(outputStream* st) const { diff --git a/hotspot/src/share/vm/opto/connode.cpp b/hotspot/src/share/vm/opto/connode.cpp index 9a3b65031ae..7e072ff4413 100644 --- a/hotspot/src/share/vm/opto/connode.cpp +++ b/hotspot/src/share/vm/opto/connode.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1051,6 +1051,7 @@ Node *ConvL2INode::Ideal(PhaseGVN *phase, bool can_reshape) { //------------------------------Value------------------------------------------ const Type *CastX2PNode::Value( PhaseTransform *phase ) const { const Type* t = phase->type(in(1)); + if (t == Type::TOP) return Type::TOP; if (t->base() == Type_X && t->singleton()) { uintptr_t bits = (uintptr_t) t->is_intptr_t()->get_con(); if (bits == 0) return TypePtr::NULL_PTR; @@ -1121,6 +1122,7 @@ Node *CastX2PNode::Identity( PhaseTransform *phase ) { //------------------------------Value------------------------------------------ const Type *CastP2XNode::Value( PhaseTransform *phase ) const { const Type* t = phase->type(in(1)); + if (t == Type::TOP) return Type::TOP; if (t->base() == Type::RawPtr && t->singleton()) { uintptr_t bits = (uintptr_t) t->is_rawptr()->get_con(); return TypeX::make(bits); diff --git a/hotspot/src/share/vm/opto/escape.cpp b/hotspot/src/share/vm/opto/escape.cpp index 27fd8171a8c..d7c67e252d0 100644 --- a/hotspot/src/share/vm/opto/escape.cpp +++ b/hotspot/src/share/vm/opto/escape.cpp @@ -2035,40 +2035,14 @@ void ConnectionGraph::find_init_values(Node* alloc, VectorSet* visited, PhaseTra Node* store = ini->find_captured_store(offset, type2aelembytes(ft), phase); if (store != NULL && store->is_Store()) { value = store->in(MemNode::ValueIn); - } else if (ptn->edge_count() > 0) { // Are there oop stores? - // Check for a store which follows allocation without branches. + } else { + // There could be initializing stores which follow allocation. // For example, a volatile field store is not collected - // by Initialize node. TODO: it would be nice to use idom() here. + // by Initialize node. // - // Search all references to the same field which use different - // AddP nodes, for example, in the next case: - // - // Point p[] = new Point[1]; - // if ( x ) { p[0] = new Point(); p[0].x = x; } - // if ( p[0] != null ) { y = p[0].x; } // has CastPP - // - for (uint next = ei; (next < ae_cnt) && (value == NULL); next++) { - uint fpi = pta->edge_target(next); // Field (AddP) - PointsToNode *ptf = ptnode_adr(fpi); - if (ptf->offset() == offset) { - Node* nf = ptf->_node; - for (DUIterator_Fast imax, i = nf->fast_outs(imax); i < imax; i++) { - store = nf->fast_out(i); - if (store->is_Store() && store->in(0) != NULL) { - Node* ctrl = store->in(0); - while(!(ctrl == ini || ctrl == alloc || ctrl == NULL || - ctrl == C->root() || ctrl == C->top() || ctrl->is_Region() || - ctrl->is_IfTrue() || ctrl->is_IfFalse())) { - ctrl = ctrl->in(0); - } - if (ctrl == ini || ctrl == alloc) { - value = store->in(MemNode::ValueIn); - break; - } - } - } - } - } + // Need to check for dependent loads to separate such stores from + // stores which follow loads. For now, add initial value NULL so + // that compare pointers optimization works correctly. } } if (value == NULL || value != ptnode_adr(value->_idx)->_node) { diff --git a/hotspot/src/share/vm/runtime/interfaceSupport.hpp b/hotspot/src/share/vm/runtime/interfaceSupport.hpp index e1001eea10c..2875ee0eb83 100644 --- a/hotspot/src/share/vm/runtime/interfaceSupport.hpp +++ b/hotspot/src/share/vm/runtime/interfaceSupport.hpp @@ -436,6 +436,7 @@ class RuntimeHistogramElement : public HistogramElement { #define VM_LEAF_BASE(result_type, header) \ TRACE_CALL(result_type, header) \ debug_only(NoHandleMark __hm;) \ + os::verify_stack_alignment(); \ /* begin of body */ @@ -445,6 +446,7 @@ class RuntimeHistogramElement : public HistogramElement { TRACE_CALL(result_type, header) \ HandleMarkCleaner __hm(thread); \ Thread* THREAD = thread; \ + os::verify_stack_alignment(); \ /* begin of body */ @@ -454,6 +456,7 @@ class RuntimeHistogramElement : public HistogramElement { TRACE_CALL(result_type, header) \ debug_only(NoHandleMark __hm;) \ Thread* THREAD = thread; \ + os::verify_stack_alignment(); \ /* begin of body */ diff --git a/hotspot/src/share/vm/runtime/os.hpp b/hotspot/src/share/vm/runtime/os.hpp index e77f3ce919a..dd163e9a958 100644 --- a/hotspot/src/share/vm/runtime/os.hpp +++ b/hotspot/src/share/vm/runtime/os.hpp @@ -404,6 +404,8 @@ class os: AllStatic { static address current_stack_base(); static size_t current_stack_size(); + static void verify_stack_alignment() PRODUCT_RETURN; + static int message_box(const char* title, const char* message); static char* do_you_want_to_debug(const char* message); diff --git a/hotspot/src/share/vm/services/diagnosticCommand.cpp b/hotspot/src/share/vm/services/diagnosticCommand.cpp index 78f4c223988..107b1abe510 100644 --- a/hotspot/src/share/vm/services/diagnosticCommand.cpp +++ b/hotspot/src/share/vm/services/diagnosticCommand.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -49,6 +49,11 @@ void DCmdRegistrant::register_dcmds(){ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(true, false)); DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(true, false)); + //Enhanced JMX Agent Support + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(true,false)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(true,false)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(true,false)); + } #ifndef HAVE_EXTRA_DCMD @@ -344,3 +349,185 @@ int ThreadDumpDCmd::num_arguments() { return 0; } } + +// Enhanced JMX Agent support + +JMXStartRemoteDCmd::JMXStartRemoteDCmd(outputStream *output, bool heap_allocated) : + + DCmdWithParser(output, heap_allocated), + + _config_file + ("config.file", + "set com.sun.management.config.file", "STRING", false), + + _jmxremote_port + ("jmxremote.port", + "set com.sun.management.jmxremote.port", "STRING", false), + + _jmxremote_rmi_port + ("jmxremote.rmi.port", + "set com.sun.management.jmxremote.rmi.port", "STRING", false), + + _jmxremote_ssl + ("jmxremote.ssl", + "set com.sun.management.jmxremote.ssl", "STRING", false), + + _jmxremote_registry_ssl + ("jmxremote.registry.ssl", + "set com.sun.management.jmxremote.registry.ssl", "STRING", false), + + _jmxremote_authenticate + ("jmxremote.authenticate", + "set com.sun.management.jmxremote.authenticate", "STRING", false), + + _jmxremote_password_file + ("jmxremote.password.file", + "set com.sun.management.jmxremote.password.file", "STRING", false), + + _jmxremote_access_file + ("jmxremote.access.file", + "set com.sun.management.jmxremote.access.file", "STRING", false), + + _jmxremote_login_config + ("jmxremote.login.config", + "set com.sun.management.jmxremote.login.config", "STRING", false), + + _jmxremote_ssl_enabled_cipher_suites + ("jmxremote.ssl.enabled.cipher.suites", + "set com.sun.management.jmxremote.ssl.enabled.cipher.suite", "STRING", false), + + _jmxremote_ssl_enabled_protocols + ("jmxremote.ssl.enabled.protocols", + "set com.sun.management.jmxremote.ssl.enabled.protocols", "STRING", false), + + _jmxremote_ssl_need_client_auth + ("jmxremote.ssl.need.client.auth", + "set com.sun.management.jmxremote.need.client.auth", "STRING", false), + + _jmxremote_ssl_config_file + ("jmxremote.ssl.config.file", + "set com.sun.management.jmxremote.ssl_config_file", "STRING", false) + + { + _dcmdparser.add_dcmd_option(&_config_file); + _dcmdparser.add_dcmd_option(&_jmxremote_port); + _dcmdparser.add_dcmd_option(&_jmxremote_rmi_port); + _dcmdparser.add_dcmd_option(&_jmxremote_ssl); + _dcmdparser.add_dcmd_option(&_jmxremote_registry_ssl); + _dcmdparser.add_dcmd_option(&_jmxremote_authenticate); + _dcmdparser.add_dcmd_option(&_jmxremote_password_file); + _dcmdparser.add_dcmd_option(&_jmxremote_access_file); + _dcmdparser.add_dcmd_option(&_jmxremote_login_config); + _dcmdparser.add_dcmd_option(&_jmxremote_ssl_enabled_cipher_suites); + _dcmdparser.add_dcmd_option(&_jmxremote_ssl_enabled_protocols); + _dcmdparser.add_dcmd_option(&_jmxremote_ssl_need_client_auth); + _dcmdparser.add_dcmd_option(&_jmxremote_ssl_config_file); +} + + +int JMXStartRemoteDCmd::num_arguments() { + ResourceMark rm; + JMXStartRemoteDCmd* dcmd = new JMXStartRemoteDCmd(NULL, false); + if (dcmd != NULL) { + DCmdMark mark(dcmd); + return dcmd->_dcmdparser.num_arguments(); + } else { + return 0; + } +} + + +void JMXStartRemoteDCmd::execute(TRAPS) { + ResourceMark rm(THREAD); + HandleMark hm(THREAD); + + // Load and initialize the sun.management.Agent class + // invoke startRemoteManagementAgent(string) method to start + // the remote management server. + // throw java.lang.NoSuchMethodError if the method doesn't exist + + Handle loader = Handle(THREAD, SystemDictionary::java_system_loader()); + klassOop k = SystemDictionary::resolve_or_fail(vmSymbols::sun_management_Agent(), loader, Handle(), true, CHECK); + instanceKlassHandle ik (THREAD, k); + + JavaValue result(T_VOID); + + // Pass all command line arguments to java as key=value,... + // All checks are done on java side + + int len = 0; + stringStream options; + char comma[2] = {0,0}; + + // Leave default values on Agent.class side and pass only + // agruments explicitly set by user. All arguments passed + // to jcmd override properties with the same name set by + // command line with -D or by managmenent.properties + // file. +#define PUT_OPTION(a) \ + if ( (a).is_set() ){ \ + options.print("%scom.sun.management.%s=%s", comma, (a).name(), (a).value()); \ + comma[0] = ','; \ + } + + PUT_OPTION(_config_file); + PUT_OPTION(_jmxremote_port); + PUT_OPTION(_jmxremote_rmi_port); + PUT_OPTION(_jmxremote_ssl); + PUT_OPTION(_jmxremote_registry_ssl); + PUT_OPTION(_jmxremote_authenticate); + PUT_OPTION(_jmxremote_password_file); + PUT_OPTION(_jmxremote_access_file); + PUT_OPTION(_jmxremote_login_config); + PUT_OPTION(_jmxremote_ssl_enabled_cipher_suites); + PUT_OPTION(_jmxremote_ssl_enabled_protocols); + PUT_OPTION(_jmxremote_ssl_need_client_auth); + PUT_OPTION(_jmxremote_ssl_config_file); + +#undef PUT_OPTION + + Handle str = java_lang_String::create_from_str(options.as_string(), CHECK); + JavaCalls::call_static(&result, ik, vmSymbols::startRemoteAgent_name(), vmSymbols::string_void_signature(), str, CHECK); +} + +JMXStartLocalDCmd::JMXStartLocalDCmd(outputStream *output, bool heap_allocated) : + DCmd(output, heap_allocated) +{ + // do nothing +} + +void JMXStartLocalDCmd::execute(TRAPS) { + ResourceMark rm(THREAD); + HandleMark hm(THREAD); + + // Load and initialize the sun.management.Agent class + // invoke startLocalManagementAgent(void) method to start + // the local management server + // throw java.lang.NoSuchMethodError if method doesn't exist + + Handle loader = Handle(THREAD, SystemDictionary::java_system_loader()); + klassOop k = SystemDictionary::resolve_or_fail(vmSymbols::sun_management_Agent(), loader, Handle(), true, CHECK); + instanceKlassHandle ik (THREAD, k); + + JavaValue result(T_VOID); + JavaCalls::call_static(&result, ik, vmSymbols::startLocalAgent_name(), vmSymbols::void_method_signature(), CHECK); +} + + +void JMXStopRemoteDCmd::execute(TRAPS) { + ResourceMark rm(THREAD); + HandleMark hm(THREAD); + + // Load and initialize the sun.management.Agent class + // invoke stopRemoteManagementAgent method to stop the + // management server + // throw java.lang.NoSuchMethodError if method doesn't exist + + Handle loader = Handle(THREAD, SystemDictionary::java_system_loader()); + klassOop k = SystemDictionary::resolve_or_fail(vmSymbols::sun_management_Agent(), loader, Handle(), true, CHECK); + instanceKlassHandle ik (THREAD, k); + + JavaValue result(T_VOID); + JavaCalls::call_static(&result, ik, vmSymbols::stopRemoteAgent_name(), vmSymbols::void_method_signature(), CHECK); +} + diff --git a/hotspot/src/share/vm/services/diagnosticCommand.hpp b/hotspot/src/share/vm/services/diagnosticCommand.hpp index c226a4ad6e9..d5c5cd172aa 100644 --- a/hotspot/src/share/vm/services/diagnosticCommand.hpp +++ b/hotspot/src/share/vm/services/diagnosticCommand.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -214,4 +214,82 @@ public: virtual void execute(TRAPS); }; +// Enhanced JMX Agent support + +class JMXStartRemoteDCmd : public DCmdWithParser { + + // Explicitly list all properties that could be + // passed to Agent.startRemoteManagementAgent() + // com.sun.management is omitted + + DCmdArgument _config_file; + DCmdArgument _jmxremote_port; + DCmdArgument _jmxremote_rmi_port; + DCmdArgument _jmxremote_ssl; + DCmdArgument _jmxremote_registry_ssl; + DCmdArgument _jmxremote_authenticate; + DCmdArgument _jmxremote_password_file; + DCmdArgument _jmxremote_access_file; + DCmdArgument _jmxremote_login_config; + DCmdArgument _jmxremote_ssl_enabled_cipher_suites; + DCmdArgument _jmxremote_ssl_enabled_protocols; + DCmdArgument _jmxremote_ssl_need_client_auth; + DCmdArgument _jmxremote_ssl_config_file; + +public: + JMXStartRemoteDCmd(outputStream *output, bool heap_allocated); + + static const char *name() { + return "ManagementAgent.start"; + } + + static const char *description() { + return "Start remote management agent."; + } + + static int num_arguments(); + + virtual void execute(TRAPS); + +}; + +class JMXStartLocalDCmd : public DCmd { + + // Explicitly request start of local agent, + // it will not be started by start dcmd + + +public: + JMXStartLocalDCmd(outputStream *output, bool heap_allocated); + + static const char *name() { + return "ManagementAgent.start_local"; + } + + static const char *description() { + return "Start local management agent."; + } + + virtual void execute(TRAPS); + +}; + +class JMXStopRemoteDCmd : public DCmd { +public: + JMXStopRemoteDCmd(outputStream *output, bool heap_allocated) : + DCmd(output, heap_allocated) { + // Do Nothing + } + + static const char *name() { + return "ManagementAgent.stop"; + } + + static const char *description() { + return "Stop remote management agent."; + } + + virtual void execute(TRAPS); +}; + #endif // SHARE_VM_SERVICES_DIAGNOSTICCOMMAND_HPP diff --git a/jaxp/.hgtags b/jaxp/.hgtags index 4fbc5eb0f97..92799ab0e9f 100644 --- a/jaxp/.hgtags +++ b/jaxp/.hgtags @@ -149,3 +149,4 @@ cf9d6ec44f891236ad18451021d6dcd57dc82f7b jdk8-b22 bb694c151fc7b5c8f9edc8af6a80738530feacaf jdk8-b25 dbb7283c197b27da1fc12ae8a83785c851b68c12 jdk8-b26 80c47eb83d24fdd64bbb48f288bd6d4f03e0ec88 jdk8-b27 +f3244c1f04864d35c41fa8d13669faf4f65b81e2 jdk8-b28 diff --git a/jaxp/README b/jaxp/README index f5462658425..4d65125b34c 100644 --- a/jaxp/README +++ b/jaxp/README @@ -17,9 +17,3 @@ Simple Build Instructions: "dist" directory. Help information is available by running "ant -projecthelp" or "make help". -Drop Repository: - This repository builds sources from a created "drop" source directory. - These files will normally be copied from a shared directory area or - downloaded from a public website. - See the ant build script (build.xml) for more details. - diff --git a/jaxp/build-defs.xml b/jaxp/build-defs.xml deleted file mode 100644 index 7b83ad58066..00000000000 --- a/jaxp/build-defs.xml +++ /dev/null @@ -1,122 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/jaxp/build-drop-template.xml b/jaxp/build-drop-template.xml deleted file mode 100644 index a593b428d13..00000000000 --- a/jaxp/build-drop-template.xml +++ /dev/null @@ -1,144 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Checksum on file ${@DROP@.bundle.copy} is - ${@DROP@.bundle.md5.checksum.is}, not ${@DROP@.bundle.md5.checksum} - - - - - - - - - - - - - - - - - - - diff --git a/jaxp/build.properties b/jaxp/build.properties index a468f8175fc..9240acc57f8 100644 --- a/jaxp/build.properties +++ b/jaxp/build.properties @@ -23,10 +23,6 @@ # questions. # -# Base locations where bundles are located -slashjava=/java -drops.dir=${slashjava}/devtools/share/jdk8-drops - # This is the JDK used to build and run the bootstrap version of javac. # The bootstrap javac is used to compile both boostrap versions of the # other tools, and product versions of all the tools. @@ -68,15 +64,6 @@ dist.lib.dir=${dist.dir}/lib dist.classes.jar=${dist.lib.dir}/classes.jar dist.src.zip=${dist.lib.dir}/src.zip -# Where all drop sources get placed when downloaded and unzipped -drop.expanded.dir=${output.dir}/drop - -# Location if the sources were included already -drop.included.dir=./drop_included - -# Where patches to drop bundle sources live -patches.dir=patches - # Sanity information sanity.info= Sanity Settings:${line.separator}\ ant.home=${ant.home}${line.separator}\ @@ -100,28 +87,6 @@ sanity.info= Sanity Settings:${line.separator}\ output.dir=${output.dir}${line.separator}\ build.dir=${build.dir}${line.separator}\ dist.dir=${dist.dir}${line.separator}\ - drop.dir=${drop.dir}${line.separator}\ - drops.dir=${drops.dir}${line.separator}\ -${line.separator} - -# Failure messages when source cannot be found on the file system -failed.nourl.src.message=\ -ERROR: Cannot find source for project ${ant.project.name}.\ -${line.separator}${line.separator}\ -HINT: Try setting drops.dir to indicate where the bundles can be found, \ -or try setting the ant property allow.downloads=true to download the bundle from the URL.\ -${line.separator}\ -e.g. ant -Dallow.downloads=true -OR- ant -Ddrops.dir=some_directory \ -${line.separator} - -# Failure message when source cannot be downloaded -failed.url.src.message=\ -ERROR: Cannot find source for project ${ant.project.name}.\ -${line.separator}${line.separator}\ -HINT: Try setting drops.dir to indicate where the bundles can be found, \ -or try checking the URL with your browser.\ -${line.separator}\ -e.g. ant -Ddrops.dir=some_directory \ ${line.separator} #------------------------------------------------------------ diff --git a/jaxp/build.xml b/jaxp/build.xml index 9a5897beac5..437ad0f74df 100644 --- a/jaxp/build.xml +++ b/jaxp/build.xml @@ -36,9 +36,6 @@ javac.debug - true or false for debug classfiles javac.target - classfile version target javac.source - source version - drops.dir - directory that holds source drop bundles - allow.download - permit downloads from public url (default is false) - (used if bundles not found in drops.dir) Run 'make help' for help using the Makefile. @@ -46,15 +43,11 @@ - - - - - - - + + + + + @@ -82,11 +75,11 @@ + depends="init"> @@ -97,22 +90,35 @@ - + + + + + + + + + + + + + + + depends="init"> + depends="init, dist"> - - - - - - - - @@ -163,7 +159,6 @@ - diff --git a/jaxp/make/Makefile b/jaxp/make/Makefile index b2574d7d6da..12f13281abf 100644 --- a/jaxp/make/Makefile +++ b/jaxp/make/Makefile @@ -91,23 +91,6 @@ else endif endif -# Do we have the drops already downloaded? -# Check ALT_DROPS_DIR for a full path first, -# before trying to use the devtools path, -# either via ALT_JDK_DEVTOOLS_DIR or /java/devtools. -ifdef ALT_DROPS_DIR - DROPS_DIR = $(ALT_DROPS_DIR) -else - ifdef ALT_JDK_DEVTOOLS_DIR - DROPS_DIR = $(ALT_JDK_DEVTOOLS_DIR)/share/jdk8-drops - else - DROPS_DIR = $(_SLASHJAVA)/devtools/share/jdk8-drops - endif -endif - -# Add in path to drops already downloaded -ANT_OPTIONS += -Ddrops.dir=$(DROPS_DIR) - ifdef ALT_OUTPUTDIR OUTPUTDIR = $(ALT_OUTPUTDIR) ANT_OPTIONS += -Doutput.dir=$(ALT_OUTPUTDIR) @@ -144,13 +127,17 @@ endif default: all # All ant targets of interest -ANT_TARGETS = all source drop_included build dist clobber clean sanity +ANT_TARGETS = all build dist clobber clean sanity # Create a make target for each $(ANT_TARGETS): cd .. && $(ANT_JAVA_HOME) $(ANT) $(ANT_OPTIONS) -version cd .. && $(ANT_JAVA_HOME) $(ANT) $(ANT_OPTIONS) $@ +# Just for compat reasons, delete in future. +drop_included: +source: + # Help target define helpenvline @echo " $1";echo " $2" @@ -164,8 +151,6 @@ help: @echo " $(ANT_TARGETS)" @echo " " @echo " Environment or command line variables (all optional):" - $(call helpenvline, ALT_DROPS_DIR,\ - "Directory that contains the drop source bundles i.e. drops.dir") $(call helpenvline, ALT_BOOTDIR,\ "JAVA_HOME to use when running ant") $(call helpenvline, ALT_LANGTOOLS_DIST,\ diff --git a/jaxp/make/scripts/update_src.sh b/jaxp/make/scripts/update_src.sh new file mode 100644 index 00000000000..b1ff207b94c --- /dev/null +++ b/jaxp/make/scripts/update_src.sh @@ -0,0 +1,86 @@ +# +# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code 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 +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +# This script was used to copy the former drop source bundle source into +# the repository. Exists as a form of documentation. + +curdir="`(cd . && pwd)`" + +# Whitespace normalizer script is in the top repository. +normalizer="perl ${curdir}/../make/scripts/normalizer.pl" + +# Locations for bundle and root of source tree +tmp=/tmp +srcroot=${curdir}/src +mkdir -p ${srcroot} + +# Bundle information +drops_dir="/java/devtools/share/jdk8-drops" +url1="http://download.java.net/jaxp/1.4.5" +bundle1="jaxp145_01.zip" +srcdir1="${srcroot}/share/classes" + +# Function to get a bundle and explode it and normalize the source files. +getBundle() # drops_dir url bundlename bundledestdir srcrootdir +{ + # Get the bundle from drops_dir or downloaded + mkdir -p $4 + rm -f $4/$3 + if [ -f $1/$3 ] ; then + echo "Copy over bundle: $1/$3" + cp $1/$3 $4 + else + echo "Downloading bundle: $2/$3" + (cd $4 && wget $2/$3) + fi + # Fail if it does not exist + if [ ! -f $4/$3 ] ; then + echo "ERROR: Could not get $3" + exit 1 + fi + # Wipe it out completely + echo "Cleaning up $5" + rm -f -r $5 + mkdir -p $5 + echo "Unzipping $4/$3" + ( cd $5 && unzip -q $4/$3 && mv src/* . && rmdir src && rm LICENSE ) + # Run whitespace normalizer + echo "Normalizing the sources in $5" + ( cd $5 && ${normalizer} . ) + # Delete the bundle and leftover files + rm -f $4/$3 $5/filelist +} + +# Process the bundles. +getBundle "${drops_dir}" "${url1}" "${bundle1}" ${tmp} ${srcdir1} +echo "Completed bundle extraction." +echo " " + +# Appropriate Mercurial commands needed to run: +echo "Run: hg addremove src" +echo "Run: ksh ../make/scripts/webrev.ksh -N -o ${HOME}/webrev" +echo "Get reviewer, get CR, then..." +echo "Run: hg commit" + diff --git a/jaxp/patches/jaxp_src/README b/jaxp/patches/jaxp_src/README deleted file mode 100644 index 644dff0223b..00000000000 --- a/jaxp/patches/jaxp_src/README +++ /dev/null @@ -1,5 +0,0 @@ - -This directory will hold any patches that need to be applied to the drop files. - -The patch order is defined in the ant build script properties. - diff --git a/jaxp/src/share/classes/com/sun/java_cup/internal/runtime/Scanner.java b/jaxp/src/share/classes/com/sun/java_cup/internal/runtime/Scanner.java new file mode 100644 index 00000000000..a390688fd38 --- /dev/null +++ b/jaxp/src/share/classes/com/sun/java_cup/internal/runtime/Scanner.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.java_cup.internal.runtime; + +/** + * Defines the Scanner interface, which CUP uses in the default + * implementation of lr_parser.scan(). Integration + * of scanners implementing Scanner is facilitated. + * + * @author David MacMahon + */ + +/* ************************************************* + Interface Scanner + + Declares the next_token() method that should be + implemented by scanners. This method is typically + called by lr_parser.scan(). + ***************************************************/ +public interface Scanner { + public Symbol next_token() throws java.lang.Exception; +} diff --git a/jaxp/src/share/classes/com/sun/java_cup/internal/runtime/Symbol.java b/jaxp/src/share/classes/com/sun/java_cup/internal/runtime/Symbol.java new file mode 100644 index 00000000000..d25e2e837e1 --- /dev/null +++ b/jaxp/src/share/classes/com/sun/java_cup/internal/runtime/Symbol.java @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.java_cup.internal.runtime; + +/** + * Defines the Symbol class, which is used to represent all terminals + * and nonterminals while parsing. The lexer should pass CUP Symbols + * and CUP returns a Symbol. + * + * @author Frank Flannery + */ + +/* **************************************************************** + Class Symbol + what the parser expects to receive from the lexer. + the token is identified as follows: + sym: the symbol type + parse_state: the parse state. + value: is the lexical value of type Object + left : is the left position in the original input file + right: is the right position in the original input file +******************************************************************/ + +public class Symbol { + +/******************************* + Constructor for l,r values + *******************************/ + + public Symbol(int id, int l, int r, Object o) { + this(id); + left = l; + right = r; + value = o; + } + +/******************************* + Constructor for no l,r values +********************************/ + + public Symbol(int id, Object o) { + this(id); + left = -1; + right = -1; + value = o; + } + +/***************************** + Constructor for no value + ***************************/ + + public Symbol(int sym_num, int l, int r) { + sym = sym_num; + left = l; + right = r; + value = null; + } + +/*********************************** + Constructor for no value or l,r +***********************************/ + + public Symbol(int sym_num) { + this(sym_num, -1); + left = -1; + right = -1; + value = null; + } + +/*********************************** + Constructor to give a start state +***********************************/ + public Symbol(int sym_num, int state) + { + sym = sym_num; + parse_state = state; + } + +/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** The symbol number of the terminal or non terminal being represented */ + public int sym; + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** The parse state to be recorded on the parse stack with this symbol. + * This field is for the convenience of the parser and shouldn't be + * modified except by the parser. + */ + public int parse_state; + /** This allows us to catch some errors caused by scanners recycling + * symbols. For the use of the parser only. [CSA, 23-Jul-1999] */ + boolean used_by_parser = false; + +/******************************* + The data passed to parser + *******************************/ + + public int left, right; + public Object value; + + /***************************** + Printing this token out. (Override for pretty-print). + ****************************/ + public String toString() { return "#"+sym; } +} diff --git a/jaxp/src/share/classes/com/sun/java_cup/internal/runtime/lr_parser.java b/jaxp/src/share/classes/com/sun/java_cup/internal/runtime/lr_parser.java new file mode 100644 index 00000000000..a94dff88924 --- /dev/null +++ b/jaxp/src/share/classes/com/sun/java_cup/internal/runtime/lr_parser.java @@ -0,0 +1,1251 @@ +/* + * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +package com.sun.java_cup.internal.runtime; + +import java.util.Stack; + +/** This class implements a skeleton table driven LR parser. In general, + * LR parsers are a form of bottom up shift-reduce parsers. Shift-reduce + * parsers act by shifting input onto a parse stack until the Symbols + * matching the right hand side of a production appear on the top of the + * stack. Once this occurs, a reduce is performed. This involves removing + * the Symbols corresponding to the right hand side of the production + * (the so called "handle") and replacing them with the non-terminal from + * the left hand side of the production.

+ * + * To control the decision of whether to shift or reduce at any given point, + * the parser uses a state machine (the "viable prefix recognition machine" + * built by the parser generator). The current state of the machine is placed + * on top of the parse stack (stored as part of a Symbol object representing + * a terminal or non terminal). The parse action table is consulted + * (using the current state and the current lookahead Symbol as indexes) to + * determine whether to shift or to reduce. When the parser shifts, it + * changes to a new state by pushing a new Symbol (containing a new state) + * onto the stack. When the parser reduces, it pops the handle (right hand + * side of a production) off the stack. This leaves the parser in the state + * it was in before any of those Symbols were matched. Next the reduce-goto + * table is consulted (using the new state and current lookahead Symbol as + * indexes) to determine a new state to go to. The parser then shifts to + * this goto state by pushing the left hand side Symbol of the production + * (also containing the new state) onto the stack.

+ * + * This class actually provides four LR parsers. The methods parse() and + * debug_parse() provide two versions of the main parser (the only difference + * being that debug_parse() emits debugging trace messages as it parses). + * In addition to these main parsers, the error recovery mechanism uses two + * more. One of these is used to simulate "parsing ahead" in the input + * without carrying out actions (to verify that a potential error recovery + * has worked), and the other is used to parse through buffered "parse ahead" + * input in order to execute all actions and re-synchronize the actual parser + * configuration.

+ * + * This is an abstract class which is normally filled out by a subclass + * generated by the JavaCup parser generator. In addition to supplying + * the actual parse tables, generated code also supplies methods which + * invoke various pieces of user supplied code, provide access to certain + * special Symbols (e.g., EOF and error), etc. Specifically, the following + * abstract methods are normally supplied by generated code: + *

+ *
short[][] production_table() + *
Provides a reference to the production table (indicating the index of + * the left hand side non terminal and the length of the right hand side + * for each production in the grammar). + *
short[][] action_table() + *
Provides a reference to the parse action table. + *
short[][] reduce_table() + *
Provides a reference to the reduce-goto table. + *
int start_state() + *
Indicates the index of the start state. + *
int start_production() + *
Indicates the index of the starting production. + *
int EOF_sym() + *
Indicates the index of the EOF Symbol. + *
int error_sym() + *
Indicates the index of the error Symbol. + *
Symbol do_action() + *
Executes a piece of user supplied action code. This always comes at + * the point of a reduce in the parse, so this code also allocates and + * fills in the left hand side non terminal Symbol object that is to be + * pushed onto the stack for the reduce. + *
void init_actions() + *
Code to initialize a special object that encapsulates user supplied + * actions (this object is used by do_action() to actually carry out the + * actions). + *
+ * + * In addition to these routines that must be supplied by the + * generated subclass there are also a series of routines that may + * be supplied. These include: + *
+ *
Symbol scan() + *
Used to get the next input Symbol from the scanner. + *
Scanner getScanner() + *
Used to provide a scanner for the default implementation of + * scan(). + *
int error_sync_size() + *
This determines how many Symbols past the point of an error + * must be parsed without error in order to consider a recovery to + * be valid. This defaults to 3. Values less than 2 are not + * recommended. + *
void report_error(String message, Object info) + *
This method is called to report an error. The default implementation + * simply prints a message to System.err and where the error occurred. + * This method is often replaced in order to provide a more sophisticated + * error reporting mechanism. + *
void report_fatal_error(String message, Object info) + *
This method is called when a fatal error that cannot be recovered from + * is encountered. In the default implementation, it calls + * report_error() to emit a message, then throws an exception. + *
void syntax_error(Symbol cur_token) + *
This method is called as soon as syntax error is detected (but + * before recovery is attempted). In the default implementation it + * invokes: report_error("Syntax error", null); + *
void unrecovered_syntax_error(Symbol cur_token) + *
This method is called if syntax error recovery fails. In the default + * implementation it invokes:
+ * report_fatal_error("Couldn't repair and continue parse", null); + *
+ * + * @see com.sun.java_cup.internal.runtime.Symbol + * @see com.sun.java_cup.internal.runtime.Symbol + * @see com.sun.java_cup.internal.runtime.virtual_parse_stack + * @author Frank Flannery + */ + +public abstract class lr_parser { + + /*-----------------------------------------------------------*/ + /*--- Constructor(s) ----------------------------------------*/ + /*-----------------------------------------------------------*/ + + /** Simple constructor. */ + public lr_parser() + { + /* nothing to do here */ + } + + /** Constructor that sets the default scanner. [CSA/davidm] */ + public lr_parser(Scanner s) { + this(); /* in case default constructor someday does something */ + setScanner(s); + } + + /*-----------------------------------------------------------*/ + /*--- (Access to) Static (Class) Variables ------------------*/ + /*-----------------------------------------------------------*/ + + /** The default number of Symbols after an error we much match to consider + * it recovered from. + */ + protected final static int _error_sync_size = 3; + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** The number of Symbols after an error we much match to consider it + * recovered from. + */ + protected int error_sync_size() {return _error_sync_size; } + + /*-----------------------------------------------------------*/ + /*--- (Access to) Instance Variables ------------------------*/ + /*-----------------------------------------------------------*/ + + /** Table of production information (supplied by generated subclass). + * This table contains one entry per production and is indexed by + * the negative-encoded values (reduce actions) in the action_table. + * Each entry has two parts, the index of the non-terminal on the + * left hand side of the production, and the number of Symbols + * on the right hand side. + */ + public abstract short[][] production_table(); + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** The action table (supplied by generated subclass). This table is + * indexed by state and terminal number indicating what action is to + * be taken when the parser is in the given state (i.e., the given state + * is on top of the stack) and the given terminal is next on the input. + * States are indexed using the first dimension, however, the entries for + * a given state are compacted and stored in adjacent index, value pairs + * which are searched for rather than accessed directly (see get_action()). + * The actions stored in the table will be either shifts, reduces, or + * errors. Shifts are encoded as positive values (one greater than the + * state shifted to). Reduces are encoded as negative values (one less + * than the production reduced by). Error entries are denoted by zero. + * + * @see com.sun.java_cup.internal.runtime.lr_parser#get_action + */ + public abstract short[][] action_table(); + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** The reduce-goto table (supplied by generated subclass). This + * table is indexed by state and non-terminal number and contains + * state numbers. States are indexed using the first dimension, however, + * the entries for a given state are compacted and stored in adjacent + * index, value pairs which are searched for rather than accessed + * directly (see get_reduce()). When a reduce occurs, the handle + * (corresponding to the RHS of the matched production) is popped off + * the stack. The new top of stack indicates a state. This table is + * then indexed by that state and the LHS of the reducing production to + * indicate where to "shift" to. + * + * @see com.sun.java_cup.internal.runtime.lr_parser#get_reduce + */ + public abstract short[][] reduce_table(); + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** The index of the start state (supplied by generated subclass). */ + public abstract int start_state(); + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** The index of the start production (supplied by generated subclass). */ + public abstract int start_production(); + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** The index of the end of file terminal Symbol (supplied by generated + * subclass). + */ + public abstract int EOF_sym(); + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** The index of the special error Symbol (supplied by generated subclass). */ + public abstract int error_sym(); + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Internal flag to indicate when parser should quit. */ + protected boolean _done_parsing = false; + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** This method is called to indicate that the parser should quit. This is + * normally called by an accept action, but can be used to cancel parsing + * early in other circumstances if desired. + */ + public void done_parsing() + { + _done_parsing = true; + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + /* Global parse state shared by parse(), error recovery, and + * debugging routines */ + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Indication of the index for top of stack (for use by actions). */ + protected int tos; + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** The current lookahead Symbol. */ + protected Symbol cur_token; + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** The parse stack itself. */ + protected Stack stack = new Stack(); + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Direct reference to the production table. */ + protected short[][] production_tab; + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Direct reference to the action table. */ + protected short[][] action_tab; + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Direct reference to the reduce-goto table. */ + protected short[][] reduce_tab; + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** This is the scanner object used by the default implementation + * of scan() to get Symbols. To avoid name conflicts with existing + * code, this field is private. [CSA/davidm] */ + private Scanner _scanner; + + /** + * Simple accessor method to set the default scanner. + */ + public void setScanner(Scanner s) { _scanner = s; } + + /** + * Simple accessor method to get the default scanner. + */ + public Scanner getScanner() { return _scanner; } + + /*-----------------------------------------------------------*/ + /*--- General Methods ---------------------------------------*/ + /*-----------------------------------------------------------*/ + + /** Perform a bit of user supplied action code (supplied by generated + * subclass). Actions are indexed by an internal action number assigned + * at parser generation time. + * + * @param act_num the internal index of the action to be performed. + * @param parser the parser object we are acting for. + * @param stack the parse stack of that object. + * @param top the index of the top element of the parse stack. + */ + public abstract Symbol do_action( + int act_num, + lr_parser parser, + Stack stack, + int top) + throws java.lang.Exception; + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** User code for initialization inside the parser. Typically this + * initializes the scanner. This is called before the parser requests + * the first Symbol. Here this is just a placeholder for subclasses that + * might need this and we perform no action. This method is normally + * overridden by the generated code using this contents of the "init with" + * clause as its body. + */ + public void user_init() throws java.lang.Exception { } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Initialize the action object. This is called before the parser does + * any parse actions. This is filled in by generated code to create + * an object that encapsulates all action code. + */ + protected abstract void init_actions() throws java.lang.Exception; + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Get the next Symbol from the input (supplied by generated subclass). + * Once end of file has been reached, all subsequent calls to scan + * should return an EOF Symbol (which is Symbol number 0). By default + * this method returns getScanner().next_token(); this implementation + * can be overriden by the generated parser using the code declared in + * the "scan with" clause. Do not recycle objects; every call to + * scan() should return a fresh object. + */ + public Symbol scan() throws java.lang.Exception { + return getScanner().next_token(); + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Report a fatal error. This method takes a message string and an + * additional object (to be used by specializations implemented in + * subclasses). Here in the base class a very simple implementation + * is provided which reports the error then throws an exception. + * + * @param message an error message. + * @param info an extra object reserved for use by specialized subclasses. + */ + public void report_fatal_error( + String message, + Object info) + throws java.lang.Exception + { + /* stop parsing (not really necessary since we throw an exception, but) */ + done_parsing(); + + /* use the normal error message reporting to put out the message */ + report_error(message, info); + + /* throw an exception */ + throw new Exception("Can't recover from previous error(s)"); + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Report a non fatal error (or warning). This method takes a message + * string and an additional object (to be used by specializations + * implemented in subclasses). Here in the base class a very simple + * implementation is provided which simply prints the message to + * System.err. + * + * @param message an error message. + * @param info an extra object reserved for use by specialized subclasses. + */ + public void report_error(String message, Object info) + { + System.err.print(message); + if (info instanceof Symbol) + if (((Symbol)info).left != -1) + System.err.println(" at character " + ((Symbol)info).left + + " of input"); + else System.err.println(""); + else System.err.println(""); + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** This method is called when a syntax error has been detected and recovery + * is about to be invoked. Here in the base class we just emit a + * "Syntax error" error message. + * + * @param cur_token the current lookahead Symbol. + */ + public void syntax_error(Symbol cur_token) + { + report_error("Syntax error", cur_token); + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** This method is called if it is determined that syntax error recovery + * has been unsuccessful. Here in the base class we report a fatal error. + * + * @param cur_token the current lookahead Symbol. + */ + public void unrecovered_syntax_error(Symbol cur_token) + throws java.lang.Exception + { + report_fatal_error("Couldn't repair and continue parse", cur_token); + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Fetch an action from the action table. The table is broken up into + * rows, one per state (rows are indexed directly by state number). + * Within each row, a list of index, value pairs are given (as sequential + * entries in the table), and the list is terminated by a default entry + * (denoted with a Symbol index of -1). To find the proper entry in a row + * we do a linear or binary search (depending on the size of the row). + * + * @param state the state index of the action being accessed. + * @param sym the Symbol index of the action being accessed. + */ + protected final short get_action(int state, int sym) + { + short tag; + int first, last, probe; + short[] row = action_tab[state]; + + /* linear search if we are < 10 entries */ + if (row.length < 20) + for (probe = 0; probe < row.length; probe++) + { + /* is this entry labeled with our Symbol or the default? */ + tag = row[probe++]; + if (tag == sym || tag == -1) + { + /* return the next entry */ + return row[probe]; + } + } + /* otherwise binary search */ + else + { + first = 0; + last = (row.length-1)/2 - 1; /* leave out trailing default entry */ + while (first <= last) + { + probe = (first+last)/2; + if (sym == row[probe*2]) + return row[probe*2+1]; + else if (sym > row[probe*2]) + first = probe+1; + else + last = probe-1; + } + + /* not found, use the default at the end */ + return row[row.length-1]; + } + + /* shouldn't happened, but if we run off the end we return the + default (error == 0) */ + return 0; + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Fetch a state from the reduce-goto table. The table is broken up into + * rows, one per state (rows are indexed directly by state number). + * Within each row, a list of index, value pairs are given (as sequential + * entries in the table), and the list is terminated by a default entry + * (denoted with a Symbol index of -1). To find the proper entry in a row + * we do a linear search. + * + * @param state the state index of the entry being accessed. + * @param sym the Symbol index of the entry being accessed. + */ + protected final short get_reduce(int state, int sym) + { + short tag; + short[] row = reduce_tab[state]; + + /* if we have a null row we go with the default */ + if (row == null) + return -1; + + for (int probe = 0; probe < row.length; probe++) + { + /* is this entry labeled with our Symbol or the default? */ + tag = row[probe++]; + if (tag == sym || tag == -1) + { + /* return the next entry */ + return row[probe]; + } + } + /* if we run off the end we return the default (error == -1) */ + return -1; + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** This method provides the main parsing routine. It returns only when + * done_parsing() has been called (typically because the parser has + * accepted, or a fatal error has been reported). See the header + * documentation for the class regarding how shift/reduce parsers operate + * and how the various tables are used. + */ + public Symbol parse() throws java.lang.Exception + { + /* the current action code */ + int act; + + /* the Symbol/stack element returned by a reduce */ + Symbol lhs_sym = null; + + /* information about production being reduced with */ + short handle_size, lhs_sym_num; + + /* set up direct reference to tables to drive the parser */ + + production_tab = production_table(); + action_tab = action_table(); + reduce_tab = reduce_table(); + + /* initialize the action encapsulation object */ + init_actions(); + + /* do user initialization */ + user_init(); + + /* get the first token */ + cur_token = scan(); + + /* push dummy Symbol with start state to get us underway */ + stack.removeAllElements(); + stack.push(new Symbol(0, start_state())); + tos = 0; + + /* continue until we are told to stop */ + for (_done_parsing = false; !_done_parsing; ) + { + /* Check current token for freshness. */ + if (cur_token.used_by_parser) + throw new Error("Symbol recycling detected (fix your scanner)."); + + /* current state is always on the top of the stack */ + + /* look up action out of the current state with the current input */ + act = get_action(((Symbol)stack.peek()).parse_state, cur_token.sym); + + /* decode the action -- > 0 encodes shift */ + if (act > 0) + { + /* shift to the encoded state by pushing it on the stack */ + cur_token.parse_state = act-1; + cur_token.used_by_parser = true; + stack.push(cur_token); + tos++; + + /* advance to the next Symbol */ + cur_token = scan(); + } + /* if its less than zero, then it encodes a reduce action */ + else if (act < 0) + { + /* perform the action for the reduce */ + lhs_sym = do_action((-act)-1, this, stack, tos); + + /* look up information about the production */ + lhs_sym_num = production_tab[(-act)-1][0]; + handle_size = production_tab[(-act)-1][1]; + + /* pop the handle off the stack */ + for (int i = 0; i < handle_size; i++) + { + stack.pop(); + tos--; + } + + /* look up the state to go to from the one popped back to */ + act = get_reduce(((Symbol)stack.peek()).parse_state, lhs_sym_num); + + /* shift to that state */ + lhs_sym.parse_state = act; + lhs_sym.used_by_parser = true; + stack.push(lhs_sym); + tos++; + } + /* finally if the entry is zero, we have an error */ + else if (act == 0) + { + /* call user syntax error reporting routine */ + syntax_error(cur_token); + + /* try to error recover */ + if (!error_recovery(false)) + { + /* if that fails give up with a fatal syntax error */ + unrecovered_syntax_error(cur_token); + + /* just in case that wasn't fatal enough, end parse */ + done_parsing(); + } else { + lhs_sym = (Symbol)stack.peek(); + } + } + } + return lhs_sym; + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Write a debugging message to System.err for the debugging version + * of the parser. + * + * @param mess the text of the debugging message. + */ + public void debug_message(String mess) + { + System.err.println(mess); + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Dump the parse stack for debugging purposes. */ + public void dump_stack() + { + if (stack == null) + { + debug_message("# Stack dump requested, but stack is null"); + return; + } + + debug_message("============ Parse Stack Dump ============"); + + /* dump the stack */ + for (int i=0; i"); + if ((i%3)==2 || (i==(stack.size()-1))) { + debug_message(sb.toString()); + sb = new StringBuffer(" "); + } + } + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Perform a parse with debugging output. This does exactly the + * same things as parse(), except that it calls debug_shift() and + * debug_reduce() when shift and reduce moves are taken by the parser + * and produces various other debugging messages. + */ + public Symbol debug_parse() + throws java.lang.Exception + { + /* the current action code */ + int act; + + /* the Symbol/stack element returned by a reduce */ + Symbol lhs_sym = null; + + /* information about production being reduced with */ + short handle_size, lhs_sym_num; + + /* set up direct reference to tables to drive the parser */ + production_tab = production_table(); + action_tab = action_table(); + reduce_tab = reduce_table(); + + debug_message("# Initializing parser"); + + /* initialize the action encapsulation object */ + init_actions(); + + /* do user initialization */ + user_init(); + + /* the current Symbol */ + cur_token = scan(); + + debug_message("# Current Symbol is #" + cur_token.sym); + + /* push dummy Symbol with start state to get us underway */ + stack.removeAllElements(); + stack.push(new Symbol(0, start_state())); + tos = 0; + + /* continue until we are told to stop */ + for (_done_parsing = false; !_done_parsing; ) + { + /* Check current token for freshness. */ + if (cur_token.used_by_parser) + throw new Error("Symbol recycling detected (fix your scanner)."); + + /* current state is always on the top of the stack */ + //debug_stack(); + + /* look up action out of the current state with the current input */ + act = get_action(((Symbol)stack.peek()).parse_state, cur_token.sym); + + /* decode the action -- > 0 encodes shift */ + if (act > 0) + { + /* shift to the encoded state by pushing it on the stack */ + cur_token.parse_state = act-1; + cur_token.used_by_parser = true; + debug_shift(cur_token); + stack.push(cur_token); + tos++; + + /* advance to the next Symbol */ + cur_token = scan(); + debug_message("# Current token is " + cur_token); + } + /* if its less than zero, then it encodes a reduce action */ + else if (act < 0) + { + /* perform the action for the reduce */ + lhs_sym = do_action((-act)-1, this, stack, tos); + + /* look up information about the production */ + lhs_sym_num = production_tab[(-act)-1][0]; + handle_size = production_tab[(-act)-1][1]; + + debug_reduce((-act)-1, lhs_sym_num, handle_size); + + /* pop the handle off the stack */ + for (int i = 0; i < handle_size; i++) + { + stack.pop(); + tos--; + } + + /* look up the state to go to from the one popped back to */ + act = get_reduce(((Symbol)stack.peek()).parse_state, lhs_sym_num); + debug_message("# Reduce rule: top state " + + ((Symbol)stack.peek()).parse_state + + ", lhs sym " + lhs_sym_num + " -> state " + act); + + /* shift to that state */ + lhs_sym.parse_state = act; + lhs_sym.used_by_parser = true; + stack.push(lhs_sym); + tos++; + + debug_message("# Goto state #" + act); + } + /* finally if the entry is zero, we have an error */ + else if (act == 0) + { + /* call user syntax error reporting routine */ + syntax_error(cur_token); + + /* try to error recover */ + if (!error_recovery(true)) + { + /* if that fails give up with a fatal syntax error */ + unrecovered_syntax_error(cur_token); + + /* just in case that wasn't fatal enough, end parse */ + done_parsing(); + } else { + lhs_sym = (Symbol)stack.peek(); + } + } + } + return lhs_sym; + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + /* Error recovery code */ + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Attempt to recover from a syntax error. This returns false if recovery + * fails, true if it succeeds. Recovery happens in 4 steps. First we + * pop the parse stack down to a point at which we have a shift out + * of the top-most state on the error Symbol. This represents the + * initial error recovery configuration. If no such configuration is + * found, then we fail. Next a small number of "lookahead" or "parse + * ahead" Symbols are read into a buffer. The size of this buffer is + * determined by error_sync_size() and determines how many Symbols beyond + * the error must be matched to consider the recovery a success. Next, + * we begin to discard Symbols in attempt to get past the point of error + * to a point where we can continue parsing. After each Symbol, we attempt + * to "parse ahead" though the buffered lookahead Symbols. The "parse ahead" + * process simulates that actual parse, but does not modify the real + * parser's configuration, nor execute any actions. If we can parse all + * the stored Symbols without error, then the recovery is considered a + * success. Once a successful recovery point is determined, we do an + * actual parse over the stored input -- modifying the real parse + * configuration and executing all actions. Finally, we return the the + * normal parser to continue with the overall parse. + * + * @param debug should we produce debugging messages as we parse. + */ + protected boolean error_recovery(boolean debug) + throws java.lang.Exception + { + if (debug) debug_message("# Attempting error recovery"); + + /* first pop the stack back into a state that can shift on error and + do that shift (if that fails, we fail) */ + if (!find_recovery_config(debug)) + { + if (debug) debug_message("# Error recovery fails"); + return false; + } + + /* read ahead to create lookahead we can parse multiple times */ + read_lookahead(); + + /* repeatedly try to parse forward until we make it the required dist */ + for (;;) + { + /* try to parse forward, if it makes it, bail out of loop */ + if (debug) debug_message("# Trying to parse ahead"); + if (try_parse_ahead(debug)) + { + break; + } + + /* if we are now at EOF, we have failed */ + if (lookahead[0].sym == EOF_sym()) + { + if (debug) debug_message("# Error recovery fails at EOF"); + return false; + } + + /* otherwise, we consume another Symbol and try again */ + if (debug) + debug_message("# Consuming Symbol #" + cur_err_token().sym); + restart_lookahead(); + } + + /* we have consumed to a point where we can parse forward */ + if (debug) debug_message("# Parse-ahead ok, going back to normal parse"); + + /* do the real parse (including actions) across the lookahead */ + parse_lookahead(debug); + + /* we have success */ + return true; + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Determine if we can shift under the special error Symbol out of the + * state currently on the top of the (real) parse stack. + */ + protected boolean shift_under_error() + { + /* is there a shift under error Symbol */ + return get_action(((Symbol)stack.peek()).parse_state, error_sym()) > 0; + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Put the (real) parse stack into error recovery configuration by + * popping the stack down to a state that can shift on the special + * error Symbol, then doing the shift. If no suitable state exists on + * the stack we return false + * + * @param debug should we produce debugging messages as we parse. + */ + protected boolean find_recovery_config(boolean debug) + { + Symbol error_token; + int act; + + if (debug) debug_message("# Finding recovery state on stack"); + + /* Remember the right-position of the top symbol on the stack */ + int right_pos = ((Symbol)stack.peek()).right; + int left_pos = ((Symbol)stack.peek()).left; + + /* pop down until we can shift under error Symbol */ + while (!shift_under_error()) + { + /* pop the stack */ + if (debug) + debug_message("# Pop stack by one, state was # " + + ((Symbol)stack.peek()).parse_state); + left_pos = ((Symbol)stack.pop()).left; + tos--; + + /* if we have hit bottom, we fail */ + if (stack.empty()) + { + if (debug) debug_message("# No recovery state found on stack"); + return false; + } + } + + /* state on top of the stack can shift under error, find the shift */ + act = get_action(((Symbol)stack.peek()).parse_state, error_sym()); + if (debug) + { + debug_message("# Recover state found (#" + + ((Symbol)stack.peek()).parse_state + ")"); + debug_message("# Shifting on error to state #" + (act-1)); + } + + /* build and shift a special error Symbol */ + error_token = new Symbol(error_sym(), left_pos, right_pos); + error_token.parse_state = act-1; + error_token.used_by_parser = true; + stack.push(error_token); + tos++; + + return true; + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Lookahead Symbols used for attempting error recovery "parse aheads". */ + protected Symbol lookahead[]; + + /** Position in lookahead input buffer used for "parse ahead". */ + protected int lookahead_pos; + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Read from input to establish our buffer of "parse ahead" lookahead + * Symbols. + */ + protected void read_lookahead() throws java.lang.Exception + { + /* create the lookahead array */ + lookahead = new Symbol[error_sync_size()]; + + /* fill in the array */ + for (int i = 0; i < error_sync_size(); i++) + { + lookahead[i] = cur_token; + cur_token = scan(); + } + + /* start at the beginning */ + lookahead_pos = 0; + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Return the current lookahead in our error "parse ahead" buffer. */ + protected Symbol cur_err_token() { return lookahead[lookahead_pos]; } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Advance to next "parse ahead" input Symbol. Return true if we have + * input to advance to, false otherwise. + */ + protected boolean advance_lookahead() + { + /* advance the input location */ + lookahead_pos++; + + /* return true if we didn't go off the end */ + return lookahead_pos < error_sync_size(); + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Reset the parse ahead input to one Symbol past where we started error + * recovery (this consumes one new Symbol from the real input). + */ + protected void restart_lookahead() throws java.lang.Exception + { + /* move all the existing input over */ + for (int i = 1; i < error_sync_size(); i++) + lookahead[i-1] = lookahead[i]; + + /* read a new Symbol into the last spot */ + cur_token = scan(); + lookahead[error_sync_size()-1] = cur_token; + + /* reset our internal position marker */ + lookahead_pos = 0; + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Do a simulated parse forward (a "parse ahead") from the current + * stack configuration using stored lookahead input and a virtual parse + * stack. Return true if we make it all the way through the stored + * lookahead input without error. This basically simulates the action of + * parse() using only our saved "parse ahead" input, and not executing any + * actions. + * + * @param debug should we produce debugging messages as we parse. + */ + protected boolean try_parse_ahead(boolean debug) + throws java.lang.Exception + { + int act; + short lhs, rhs_size; + + /* create a virtual stack from the real parse stack */ + virtual_parse_stack vstack = new virtual_parse_stack(stack); + + /* parse until we fail or get past the lookahead input */ + for (;;) + { + /* look up the action from the current state (on top of stack) */ + act = get_action(vstack.top(), cur_err_token().sym); + + /* if its an error, we fail */ + if (act == 0) return false; + + /* > 0 encodes a shift */ + if (act > 0) + { + /* push the new state on the stack */ + vstack.push(act-1); + + if (debug) debug_message("# Parse-ahead shifts Symbol #" + + cur_err_token().sym + " into state #" + (act-1)); + + /* advance simulated input, if we run off the end, we are done */ + if (!advance_lookahead()) return true; + } + /* < 0 encodes a reduce */ + else + { + /* if this is a reduce with the start production we are done */ + if ((-act)-1 == start_production()) + { + if (debug) debug_message("# Parse-ahead accepts"); + return true; + } + + /* get the lhs Symbol and the rhs size */ + lhs = production_tab[(-act)-1][0]; + rhs_size = production_tab[(-act)-1][1]; + + /* pop handle off the stack */ + for (int i = 0; i < rhs_size; i++) + vstack.pop(); + + if (debug) + debug_message("# Parse-ahead reduces: handle size = " + + rhs_size + " lhs = #" + lhs + " from state #" + vstack.top()); + + /* look up goto and push it onto the stack */ + vstack.push(get_reduce(vstack.top(), lhs)); + if (debug) + debug_message("# Goto state #" + vstack.top()); + } + } + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Parse forward using stored lookahead Symbols. In this case we have + * already verified that parsing will make it through the stored lookahead + * Symbols and we are now getting back to the point at which we can hand + * control back to the normal parser. Consequently, this version of the + * parser performs all actions and modifies the real parse configuration. + * This returns once we have consumed all the stored input or we accept. + * + * @param debug should we produce debugging messages as we parse. + */ + protected void parse_lookahead(boolean debug) + throws java.lang.Exception + { + /* the current action code */ + int act; + + /* the Symbol/stack element returned by a reduce */ + Symbol lhs_sym = null; + + /* information about production being reduced with */ + short handle_size, lhs_sym_num; + + /* restart the saved input at the beginning */ + lookahead_pos = 0; + + if (debug) + { + debug_message("# Reparsing saved input with actions"); + debug_message("# Current Symbol is #" + cur_err_token().sym); + debug_message("# Current state is #" + + ((Symbol)stack.peek()).parse_state); + } + + /* continue until we accept or have read all lookahead input */ + while(!_done_parsing) + { + /* current state is always on the top of the stack */ + + /* look up action out of the current state with the current input */ + act = + get_action(((Symbol)stack.peek()).parse_state, cur_err_token().sym); + + /* decode the action -- > 0 encodes shift */ + if (act > 0) + { + /* shift to the encoded state by pushing it on the stack */ + cur_err_token().parse_state = act-1; + cur_err_token().used_by_parser = true; + if (debug) debug_shift(cur_err_token()); + stack.push(cur_err_token()); + tos++; + + /* advance to the next Symbol, if there is none, we are done */ + if (!advance_lookahead()) + { + if (debug) debug_message("# Completed reparse"); + + /* scan next Symbol so we can continue parse */ + // BUGFIX by Chris Harris : + // correct a one-off error by commenting out + // this next line. + /*cur_token = scan();*/ + + /* go back to normal parser */ + return; + } + + if (debug) + debug_message("# Current Symbol is #" + cur_err_token().sym); + } + /* if its less than zero, then it encodes a reduce action */ + else if (act < 0) + { + /* perform the action for the reduce */ + lhs_sym = do_action((-act)-1, this, stack, tos); + + /* look up information about the production */ + lhs_sym_num = production_tab[(-act)-1][0]; + handle_size = production_tab[(-act)-1][1]; + + if (debug) debug_reduce((-act)-1, lhs_sym_num, handle_size); + + /* pop the handle off the stack */ + for (int i = 0; i < handle_size; i++) + { + stack.pop(); + tos--; + } + + /* look up the state to go to from the one popped back to */ + act = get_reduce(((Symbol)stack.peek()).parse_state, lhs_sym_num); + + /* shift to that state */ + lhs_sym.parse_state = act; + lhs_sym.used_by_parser = true; + stack.push(lhs_sym); + tos++; + + if (debug) debug_message("# Goto state #" + act); + + } + /* finally if the entry is zero, we have an error + (shouldn't happen here, but...)*/ + else if (act == 0) + { + report_fatal_error("Syntax error", lhs_sym); + return; + } + } + + + } + + /*-----------------------------------------------------------*/ + + /** Utility function: unpacks parse tables from strings */ + protected static short[][] unpackFromStrings(String[] sa) + { + // Concatanate initialization strings. + StringBuffer sb = new StringBuffer(sa[0]); + for (int i=1; i= real_stack.size()) return; + + /* get a copy of the first Symbol we have not transfered */ + stack_sym = (Symbol)real_stack.elementAt(real_stack.size()-1-real_next); + + /* record the transfer */ + real_next++; + + /* put the state number from the Symbol onto the virtual stack */ + vstack.push(new Integer(stack_sym.parse_state)); + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Indicate whether the stack is empty. */ + public boolean empty() + { + /* if vstack is empty then we were unable to transfer onto it and + the whole thing is empty. */ + return vstack.empty(); + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Return value on the top of the stack (without popping it). */ + public int top() throws java.lang.Exception + { + if (vstack.empty()) + throw new Exception( + "Internal parser error: top() called on empty virtual stack"); + + return ((Integer)vstack.peek()).intValue(); + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Pop the stack. */ + public void pop() throws java.lang.Exception + { + if (vstack.empty()) + throw new Exception( + "Internal parser error: pop from empty virtual stack"); + + /* pop it */ + vstack.pop(); + + /* if we are now empty transfer an element (if there is one) */ + if (vstack.empty()) + get_from_real(); + } + + /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ + + /** Push a state number onto the stack. */ + public void push(int state_num) + { + vstack.push(new Integer(state_num)); + } + + /*-----------------------------------------------------------*/ + +} diff --git a/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/Constants.java b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/Constants.java new file mode 100644 index 00000000000..ac4ae3e3e37 --- /dev/null +++ b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/Constants.java @@ -0,0 +1,788 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +package com.sun.org.apache.bcel.internal; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +/** + * Constants for the project, mostly defined in the JVM specification. + * + * @author M. Dahm + */ +public interface Constants { + /** Major and minor version of the code. + */ + public final static short MAJOR_1_1 = 45; + public final static short MINOR_1_1 = 3; + public final static short MAJOR_1_2 = 46; + public final static short MINOR_1_2 = 0; + public final static short MAJOR_1_3 = 47; + public final static short MINOR_1_3 = 0; + public final static short MAJOR = MAJOR_1_1; // Defaults + public final static short MINOR = MINOR_1_1; + + /** Maximum value for an unsigned short. + */ + public final static int MAX_SHORT = 65535; // 2^16 - 1 + + /** Maximum value for an unsigned byte. + */ + public final static int MAX_BYTE = 255; // 2^8 - 1 + + /** Access flags for classes, fields and methods. + */ + public final static short ACC_PUBLIC = 0x0001; + public final static short ACC_PRIVATE = 0x0002; + public final static short ACC_PROTECTED = 0x0004; + public final static short ACC_STATIC = 0x0008; + + public final static short ACC_FINAL = 0x0010; + public final static short ACC_SYNCHRONIZED = 0x0020; + public final static short ACC_VOLATILE = 0x0040; + public final static short ACC_TRANSIENT = 0x0080; + + public final static short ACC_NATIVE = 0x0100; + public final static short ACC_INTERFACE = 0x0200; + public final static short ACC_ABSTRACT = 0x0400; + public final static short ACC_STRICT = 0x0800; + + // Applies to classes compiled by new compilers only + public final static short ACC_SUPER = 0x0020; + + public final static short MAX_ACC_FLAG = ACC_STRICT; + + public final static String[] ACCESS_NAMES = { + "public", "private", "protected", "static", "final", "synchronized", + "volatile", "transient", "native", "interface", "abstract", "strictfp" + }; + + /** Tags in constant pool to denote type of constant. + */ + public final static byte CONSTANT_Utf8 = 1; + public final static byte CONSTANT_Integer = 3; + public final static byte CONSTANT_Float = 4; + public final static byte CONSTANT_Long = 5; + public final static byte CONSTANT_Double = 6; + public final static byte CONSTANT_Class = 7; + public final static byte CONSTANT_Fieldref = 9; + public final static byte CONSTANT_String = 8; + public final static byte CONSTANT_Methodref = 10; + public final static byte CONSTANT_InterfaceMethodref = 11; + public final static byte CONSTANT_NameAndType = 12; + + public final static String[] CONSTANT_NAMES = { + "", "CONSTANT_Utf8", "", "CONSTANT_Integer", + "CONSTANT_Float", "CONSTANT_Long", "CONSTANT_Double", + "CONSTANT_Class", "CONSTANT_String", "CONSTANT_Fieldref", + "CONSTANT_Methodref", "CONSTANT_InterfaceMethodref", + "CONSTANT_NameAndType" }; + + /** The name of the static initializer, also called "class + * initialization method" or "interface initialization + * method". This is "<clinit>". + */ + public final static String STATIC_INITIALIZER_NAME = ""; + + /** The name of every constructor method in a class, also called + * "instance initialization method". This is "<init>". + */ + public final static String CONSTRUCTOR_NAME = ""; + + /** The names of the interfaces implemented by arrays */ + public final static String[] INTERFACES_IMPLEMENTED_BY_ARRAYS = {"java.lang.Cloneable", "java.io.Serializable"}; + + /** + * Limitations of the Java Virtual Machine. + * See The Java Virtual Machine Specification, Second Edition, page 152, chapter 4.10. + */ + public static final int MAX_CP_ENTRIES = 65535; + public static final int MAX_CODE_SIZE = 65536; //bytes + + /** Java VM opcodes. + */ + public static final short NOP = 0; + public static final short ACONST_NULL = 1; + public static final short ICONST_M1 = 2; + public static final short ICONST_0 = 3; + public static final short ICONST_1 = 4; + public static final short ICONST_2 = 5; + public static final short ICONST_3 = 6; + public static final short ICONST_4 = 7; + public static final short ICONST_5 = 8; + public static final short LCONST_0 = 9; + public static final short LCONST_1 = 10; + public static final short FCONST_0 = 11; + public static final short FCONST_1 = 12; + public static final short FCONST_2 = 13; + public static final short DCONST_0 = 14; + public static final short DCONST_1 = 15; + public static final short BIPUSH = 16; + public static final short SIPUSH = 17; + public static final short LDC = 18; + public static final short LDC_W = 19; + public static final short LDC2_W = 20; + public static final short ILOAD = 21; + public static final short LLOAD = 22; + public static final short FLOAD = 23; + public static final short DLOAD = 24; + public static final short ALOAD = 25; + public static final short ILOAD_0 = 26; + public static final short ILOAD_1 = 27; + public static final short ILOAD_2 = 28; + public static final short ILOAD_3 = 29; + public static final short LLOAD_0 = 30; + public static final short LLOAD_1 = 31; + public static final short LLOAD_2 = 32; + public static final short LLOAD_3 = 33; + public static final short FLOAD_0 = 34; + public static final short FLOAD_1 = 35; + public static final short FLOAD_2 = 36; + public static final short FLOAD_3 = 37; + public static final short DLOAD_0 = 38; + public static final short DLOAD_1 = 39; + public static final short DLOAD_2 = 40; + public static final short DLOAD_3 = 41; + public static final short ALOAD_0 = 42; + public static final short ALOAD_1 = 43; + public static final short ALOAD_2 = 44; + public static final short ALOAD_3 = 45; + public static final short IALOAD = 46; + public static final short LALOAD = 47; + public static final short FALOAD = 48; + public static final short DALOAD = 49; + public static final short AALOAD = 50; + public static final short BALOAD = 51; + public static final short CALOAD = 52; + public static final short SALOAD = 53; + public static final short ISTORE = 54; + public static final short LSTORE = 55; + public static final short FSTORE = 56; + public static final short DSTORE = 57; + public static final short ASTORE = 58; + public static final short ISTORE_0 = 59; + public static final short ISTORE_1 = 60; + public static final short ISTORE_2 = 61; + public static final short ISTORE_3 = 62; + public static final short LSTORE_0 = 63; + public static final short LSTORE_1 = 64; + public static final short LSTORE_2 = 65; + public static final short LSTORE_3 = 66; + public static final short FSTORE_0 = 67; + public static final short FSTORE_1 = 68; + public static final short FSTORE_2 = 69; + public static final short FSTORE_3 = 70; + public static final short DSTORE_0 = 71; + public static final short DSTORE_1 = 72; + public static final short DSTORE_2 = 73; + public static final short DSTORE_3 = 74; + public static final short ASTORE_0 = 75; + public static final short ASTORE_1 = 76; + public static final short ASTORE_2 = 77; + public static final short ASTORE_3 = 78; + public static final short IASTORE = 79; + public static final short LASTORE = 80; + public static final short FASTORE = 81; + public static final short DASTORE = 82; + public static final short AASTORE = 83; + public static final short BASTORE = 84; + public static final short CASTORE = 85; + public static final short SASTORE = 86; + public static final short POP = 87; + public static final short POP2 = 88; + public static final short DUP = 89; + public static final short DUP_X1 = 90; + public static final short DUP_X2 = 91; + public static final short DUP2 = 92; + public static final short DUP2_X1 = 93; + public static final short DUP2_X2 = 94; + public static final short SWAP = 95; + public static final short IADD = 96; + public static final short LADD = 97; + public static final short FADD = 98; + public static final short DADD = 99; + public static final short ISUB = 100; + public static final short LSUB = 101; + public static final short FSUB = 102; + public static final short DSUB = 103; + public static final short IMUL = 104; + public static final short LMUL = 105; + public static final short FMUL = 106; + public static final short DMUL = 107; + public static final short IDIV = 108; + public static final short LDIV = 109; + public static final short FDIV = 110; + public static final short DDIV = 111; + public static final short IREM = 112; + public static final short LREM = 113; + public static final short FREM = 114; + public static final short DREM = 115; + public static final short INEG = 116; + public static final short LNEG = 117; + public static final short FNEG = 118; + public static final short DNEG = 119; + public static final short ISHL = 120; + public static final short LSHL = 121; + public static final short ISHR = 122; + public static final short LSHR = 123; + public static final short IUSHR = 124; + public static final short LUSHR = 125; + public static final short IAND = 126; + public static final short LAND = 127; + public static final short IOR = 128; + public static final short LOR = 129; + public static final short IXOR = 130; + public static final short LXOR = 131; + public static final short IINC = 132; + public static final short I2L = 133; + public static final short I2F = 134; + public static final short I2D = 135; + public static final short L2I = 136; + public static final short L2F = 137; + public static final short L2D = 138; + public static final short F2I = 139; + public static final short F2L = 140; + public static final short F2D = 141; + public static final short D2I = 142; + public static final short D2L = 143; + public static final short D2F = 144; + public static final short I2B = 145; + public static final short INT2BYTE = 145; // Old notion + public static final short I2C = 146; + public static final short INT2CHAR = 146; // Old notion + public static final short I2S = 147; + public static final short INT2SHORT = 147; // Old notion + public static final short LCMP = 148; + public static final short FCMPL = 149; + public static final short FCMPG = 150; + public static final short DCMPL = 151; + public static final short DCMPG = 152; + public static final short IFEQ = 153; + public static final short IFNE = 154; + public static final short IFLT = 155; + public static final short IFGE = 156; + public static final short IFGT = 157; + public static final short IFLE = 158; + public static final short IF_ICMPEQ = 159; + public static final short IF_ICMPNE = 160; + public static final short IF_ICMPLT = 161; + public static final short IF_ICMPGE = 162; + public static final short IF_ICMPGT = 163; + public static final short IF_ICMPLE = 164; + public static final short IF_ACMPEQ = 165; + public static final short IF_ACMPNE = 166; + public static final short GOTO = 167; + public static final short JSR = 168; + public static final short RET = 169; + public static final short TABLESWITCH = 170; + public static final short LOOKUPSWITCH = 171; + public static final short IRETURN = 172; + public static final short LRETURN = 173; + public static final short FRETURN = 174; + public static final short DRETURN = 175; + public static final short ARETURN = 176; + public static final short RETURN = 177; + public static final short GETSTATIC = 178; + public static final short PUTSTATIC = 179; + public static final short GETFIELD = 180; + public static final short PUTFIELD = 181; + public static final short INVOKEVIRTUAL = 182; + public static final short INVOKESPECIAL = 183; + public static final short INVOKENONVIRTUAL = 183; // Old name in JDK 1.0 + public static final short INVOKESTATIC = 184; + public static final short INVOKEINTERFACE = 185; + public static final short NEW = 187; + public static final short NEWARRAY = 188; + public static final short ANEWARRAY = 189; + public static final short ARRAYLENGTH = 190; + public static final short ATHROW = 191; + public static final short CHECKCAST = 192; + public static final short INSTANCEOF = 193; + public static final short MONITORENTER = 194; + public static final short MONITOREXIT = 195; + public static final short WIDE = 196; + public static final short MULTIANEWARRAY = 197; + public static final short IFNULL = 198; + public static final short IFNONNULL = 199; + public static final short GOTO_W = 200; + public static final short JSR_W = 201; + + /** + * Non-legal opcodes, may be used by JVM internally. + */ + public static final short BREAKPOINT = 202; + public static final short LDC_QUICK = 203; + public static final short LDC_W_QUICK = 204; + public static final short LDC2_W_QUICK = 205; + public static final short GETFIELD_QUICK = 206; + public static final short PUTFIELD_QUICK = 207; + public static final short GETFIELD2_QUICK = 208; + public static final short PUTFIELD2_QUICK = 209; + public static final short GETSTATIC_QUICK = 210; + public static final short PUTSTATIC_QUICK = 211; + public static final short GETSTATIC2_QUICK = 212; + public static final short PUTSTATIC2_QUICK = 213; + public static final short INVOKEVIRTUAL_QUICK = 214; + public static final short INVOKENONVIRTUAL_QUICK = 215; + public static final short INVOKESUPER_QUICK = 216; + public static final short INVOKESTATIC_QUICK = 217; + public static final short INVOKEINTERFACE_QUICK = 218; + public static final short INVOKEVIRTUALOBJECT_QUICK = 219; + public static final short NEW_QUICK = 221; + public static final short ANEWARRAY_QUICK = 222; + public static final short MULTIANEWARRAY_QUICK = 223; + public static final short CHECKCAST_QUICK = 224; + public static final short INSTANCEOF_QUICK = 225; + public static final short INVOKEVIRTUAL_QUICK_W = 226; + public static final short GETFIELD_QUICK_W = 227; + public static final short PUTFIELD_QUICK_W = 228; + public static final short IMPDEP1 = 254; + public static final short IMPDEP2 = 255; + + /** + * For internal purposes only. + */ + public static final short PUSH = 4711; + public static final short SWITCH = 4712; + + /** + * Illegal codes + */ + public static final short UNDEFINED = -1; + public static final short UNPREDICTABLE = -2; + public static final short RESERVED = -3; + public static final String ILLEGAL_OPCODE = ""; + public static final String ILLEGAL_TYPE = ""; + + public static final byte T_BOOLEAN = 4; + public static final byte T_CHAR = 5; + public static final byte T_FLOAT = 6; + public static final byte T_DOUBLE = 7; + public static final byte T_BYTE = 8; + public static final byte T_SHORT = 9; + public static final byte T_INT = 10; + public static final byte T_LONG = 11; + + public static final byte T_VOID = 12; // Non-standard + public static final byte T_ARRAY = 13; + public static final byte T_OBJECT = 14; + public static final byte T_REFERENCE = 14; // Deprecated + public static final byte T_UNKNOWN = 15; + public static final byte T_ADDRESS = 16; + + /** The primitive type names corresponding to the T_XX constants, + * e.g., TYPE_NAMES[T_INT] = "int" + */ + public static final String[] TYPE_NAMES = { + ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE, + "boolean", "char", "float", "double", "byte", "short", "int", "long", + "void", "array", "object", "unknown" // Non-standard + }; + + /** The primitive class names corresponding to the T_XX constants, + * e.g., CLASS_TYPE_NAMES[T_INT] = "java.lang.Integer" + */ + public static final String[] CLASS_TYPE_NAMES = { + ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE, + "java.lang.Boolean", "java.lang.Character", "java.lang.Float", + "java.lang.Double", "java.lang.Byte", "java.lang.Short", + "java.lang.Integer", "java.lang.Long", "java.lang.Void", + ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE + }; + + /** The signature characters corresponding to primitive types, + * e.g., SHORT_TYPE_NAMES[T_INT] = "I" + */ + public static final String[] SHORT_TYPE_NAMES = { + ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE, + "Z", "C", "F", "D", "B", "S", "I", "J", + "V", ILLEGAL_TYPE, ILLEGAL_TYPE, ILLEGAL_TYPE + }; + + /** + * Number of byte code operands, i.e., number of bytes after the tag byte + * itself. + */ + public static final short[] NO_OF_OPERANDS = { + 0/*nop*/, 0/*aconst_null*/, 0/*iconst_m1*/, 0/*iconst_0*/, + 0/*iconst_1*/, 0/*iconst_2*/, 0/*iconst_3*/, 0/*iconst_4*/, + 0/*iconst_5*/, 0/*lconst_0*/, 0/*lconst_1*/, 0/*fconst_0*/, + 0/*fconst_1*/, 0/*fconst_2*/, 0/*dconst_0*/, 0/*dconst_1*/, + 1/*bipush*/, 2/*sipush*/, 1/*ldc*/, 2/*ldc_w*/, 2/*ldc2_w*/, + 1/*iload*/, 1/*lload*/, 1/*fload*/, 1/*dload*/, 1/*aload*/, + 0/*iload_0*/, 0/*iload_1*/, 0/*iload_2*/, 0/*iload_3*/, + 0/*lload_0*/, 0/*lload_1*/, 0/*lload_2*/, 0/*lload_3*/, + 0/*fload_0*/, 0/*fload_1*/, 0/*fload_2*/, 0/*fload_3*/, + 0/*dload_0*/, 0/*dload_1*/, 0/*dload_2*/, 0/*dload_3*/, + 0/*aload_0*/, 0/*aload_1*/, 0/*aload_2*/, 0/*aload_3*/, + 0/*iaload*/, 0/*laload*/, 0/*faload*/, 0/*daload*/, + 0/*aaload*/, 0/*baload*/, 0/*caload*/, 0/*saload*/, + 1/*istore*/, 1/*lstore*/, 1/*fstore*/, 1/*dstore*/, + 1/*astore*/, 0/*istore_0*/, 0/*istore_1*/, 0/*istore_2*/, + 0/*istore_3*/, 0/*lstore_0*/, 0/*lstore_1*/, 0/*lstore_2*/, + 0/*lstore_3*/, 0/*fstore_0*/, 0/*fstore_1*/, 0/*fstore_2*/, + 0/*fstore_3*/, 0/*dstore_0*/, 0/*dstore_1*/, 0/*dstore_2*/, + 0/*dstore_3*/, 0/*astore_0*/, 0/*astore_1*/, 0/*astore_2*/, + 0/*astore_3*/, 0/*iastore*/, 0/*lastore*/, 0/*fastore*/, + 0/*dastore*/, 0/*aastore*/, 0/*bastore*/, 0/*castore*/, + 0/*sastore*/, 0/*pop*/, 0/*pop2*/, 0/*dup*/, 0/*dup_x1*/, + 0/*dup_x2*/, 0/*dup2*/, 0/*dup2_x1*/, 0/*dup2_x2*/, 0/*swap*/, + 0/*iadd*/, 0/*ladd*/, 0/*fadd*/, 0/*dadd*/, 0/*isub*/, + 0/*lsub*/, 0/*fsub*/, 0/*dsub*/, 0/*imul*/, 0/*lmul*/, + 0/*fmul*/, 0/*dmul*/, 0/*idiv*/, 0/*ldiv*/, 0/*fdiv*/, + 0/*ddiv*/, 0/*irem*/, 0/*lrem*/, 0/*frem*/, 0/*drem*/, + 0/*ineg*/, 0/*lneg*/, 0/*fneg*/, 0/*dneg*/, 0/*ishl*/, + 0/*lshl*/, 0/*ishr*/, 0/*lshr*/, 0/*iushr*/, 0/*lushr*/, + 0/*iand*/, 0/*land*/, 0/*ior*/, 0/*lor*/, 0/*ixor*/, 0/*lxor*/, + 2/*iinc*/, 0/*i2l*/, 0/*i2f*/, 0/*i2d*/, 0/*l2i*/, 0/*l2f*/, + 0/*l2d*/, 0/*f2i*/, 0/*f2l*/, 0/*f2d*/, 0/*d2i*/, 0/*d2l*/, + 0/*d2f*/, 0/*i2b*/, 0/*i2c*/, 0/*i2s*/, 0/*lcmp*/, 0/*fcmpl*/, + 0/*fcmpg*/, 0/*dcmpl*/, 0/*dcmpg*/, 2/*ifeq*/, 2/*ifne*/, + 2/*iflt*/, 2/*ifge*/, 2/*ifgt*/, 2/*ifle*/, 2/*if_icmpeq*/, + 2/*if_icmpne*/, 2/*if_icmplt*/, 2/*if_icmpge*/, 2/*if_icmpgt*/, + 2/*if_icmple*/, 2/*if_acmpeq*/, 2/*if_acmpne*/, 2/*goto*/, + 2/*jsr*/, 1/*ret*/, UNPREDICTABLE/*tableswitch*/, UNPREDICTABLE/*lookupswitch*/, + 0/*ireturn*/, 0/*lreturn*/, 0/*freturn*/, + 0/*dreturn*/, 0/*areturn*/, 0/*return*/, + 2/*getstatic*/, 2/*putstatic*/, 2/*getfield*/, + 2/*putfield*/, 2/*invokevirtual*/, 2/*invokespecial*/, 2/*invokestatic*/, + 4/*invokeinterface*/, UNDEFINED, 2/*new*/, + 1/*newarray*/, 2/*anewarray*/, + 0/*arraylength*/, 0/*athrow*/, 2/*checkcast*/, + 2/*instanceof*/, 0/*monitorenter*/, + 0/*monitorexit*/, UNPREDICTABLE/*wide*/, 3/*multianewarray*/, + 2/*ifnull*/, 2/*ifnonnull*/, 4/*goto_w*/, + 4/*jsr_w*/, 0/*breakpoint*/, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, RESERVED/*impdep1*/, RESERVED/*impdep2*/ + }; + + /** + * How the byte code operands are to be interpreted. + */ + public static final short[][] TYPE_OF_OPERANDS = { + {}/*nop*/, {}/*aconst_null*/, {}/*iconst_m1*/, {}/*iconst_0*/, + {}/*iconst_1*/, {}/*iconst_2*/, {}/*iconst_3*/, {}/*iconst_4*/, + {}/*iconst_5*/, {}/*lconst_0*/, {}/*lconst_1*/, {}/*fconst_0*/, + {}/*fconst_1*/, {}/*fconst_2*/, {}/*dconst_0*/, {}/*dconst_1*/, + {T_BYTE}/*bipush*/, {T_SHORT}/*sipush*/, {T_BYTE}/*ldc*/, + {T_SHORT}/*ldc_w*/, {T_SHORT}/*ldc2_w*/, + {T_BYTE}/*iload*/, {T_BYTE}/*lload*/, {T_BYTE}/*fload*/, + {T_BYTE}/*dload*/, {T_BYTE}/*aload*/, {}/*iload_0*/, + {}/*iload_1*/, {}/*iload_2*/, {}/*iload_3*/, {}/*lload_0*/, + {}/*lload_1*/, {}/*lload_2*/, {}/*lload_3*/, {}/*fload_0*/, + {}/*fload_1*/, {}/*fload_2*/, {}/*fload_3*/, {}/*dload_0*/, + {}/*dload_1*/, {}/*dload_2*/, {}/*dload_3*/, {}/*aload_0*/, + {}/*aload_1*/, {}/*aload_2*/, {}/*aload_3*/, {}/*iaload*/, + {}/*laload*/, {}/*faload*/, {}/*daload*/, {}/*aaload*/, + {}/*baload*/, {}/*caload*/, {}/*saload*/, {T_BYTE}/*istore*/, + {T_BYTE}/*lstore*/, {T_BYTE}/*fstore*/, {T_BYTE}/*dstore*/, + {T_BYTE}/*astore*/, {}/*istore_0*/, {}/*istore_1*/, + {}/*istore_2*/, {}/*istore_3*/, {}/*lstore_0*/, {}/*lstore_1*/, + {}/*lstore_2*/, {}/*lstore_3*/, {}/*fstore_0*/, {}/*fstore_1*/, + {}/*fstore_2*/, {}/*fstore_3*/, {}/*dstore_0*/, {}/*dstore_1*/, + {}/*dstore_2*/, {}/*dstore_3*/, {}/*astore_0*/, {}/*astore_1*/, + {}/*astore_2*/, {}/*astore_3*/, {}/*iastore*/, {}/*lastore*/, + {}/*fastore*/, {}/*dastore*/, {}/*aastore*/, {}/*bastore*/, + {}/*castore*/, {}/*sastore*/, {}/*pop*/, {}/*pop2*/, {}/*dup*/, + {}/*dup_x1*/, {}/*dup_x2*/, {}/*dup2*/, {}/*dup2_x1*/, + {}/*dup2_x2*/, {}/*swap*/, {}/*iadd*/, {}/*ladd*/, {}/*fadd*/, + {}/*dadd*/, {}/*isub*/, {}/*lsub*/, {}/*fsub*/, {}/*dsub*/, + {}/*imul*/, {}/*lmul*/, {}/*fmul*/, {}/*dmul*/, {}/*idiv*/, + {}/*ldiv*/, {}/*fdiv*/, {}/*ddiv*/, {}/*irem*/, {}/*lrem*/, + {}/*frem*/, {}/*drem*/, {}/*ineg*/, {}/*lneg*/, {}/*fneg*/, + {}/*dneg*/, {}/*ishl*/, {}/*lshl*/, {}/*ishr*/, {}/*lshr*/, + {}/*iushr*/, {}/*lushr*/, {}/*iand*/, {}/*land*/, {}/*ior*/, + {}/*lor*/, {}/*ixor*/, {}/*lxor*/, {T_BYTE, T_BYTE}/*iinc*/, + {}/*i2l*/, {}/*i2f*/, {}/*i2d*/, {}/*l2i*/, {}/*l2f*/, {}/*l2d*/, + {}/*f2i*/, {}/*f2l*/, {}/*f2d*/, {}/*d2i*/, {}/*d2l*/, {}/*d2f*/, + {}/*i2b*/, {}/*i2c*/,{}/*i2s*/, {}/*lcmp*/, {}/*fcmpl*/, + {}/*fcmpg*/, {}/*dcmpl*/, {}/*dcmpg*/, {T_SHORT}/*ifeq*/, + {T_SHORT}/*ifne*/, {T_SHORT}/*iflt*/, {T_SHORT}/*ifge*/, + {T_SHORT}/*ifgt*/, {T_SHORT}/*ifle*/, {T_SHORT}/*if_icmpeq*/, + {T_SHORT}/*if_icmpne*/, {T_SHORT}/*if_icmplt*/, + {T_SHORT}/*if_icmpge*/, {T_SHORT}/*if_icmpgt*/, + {T_SHORT}/*if_icmple*/, {T_SHORT}/*if_acmpeq*/, + {T_SHORT}/*if_acmpne*/, {T_SHORT}/*goto*/, {T_SHORT}/*jsr*/, + {T_BYTE}/*ret*/, {}/*tableswitch*/, {}/*lookupswitch*/, + {}/*ireturn*/, {}/*lreturn*/, {}/*freturn*/, {}/*dreturn*/, + {}/*areturn*/, {}/*return*/, {T_SHORT}/*getstatic*/, + {T_SHORT}/*putstatic*/, {T_SHORT}/*getfield*/, + {T_SHORT}/*putfield*/, {T_SHORT}/*invokevirtual*/, + {T_SHORT}/*invokespecial*/, {T_SHORT}/*invokestatic*/, + {T_SHORT, T_BYTE, T_BYTE}/*invokeinterface*/, {}, + {T_SHORT}/*new*/, {T_BYTE}/*newarray*/, + {T_SHORT}/*anewarray*/, {}/*arraylength*/, {}/*athrow*/, + {T_SHORT}/*checkcast*/, {T_SHORT}/*instanceof*/, + {}/*monitorenter*/, {}/*monitorexit*/, {T_BYTE}/*wide*/, + {T_SHORT, T_BYTE}/*multianewarray*/, {T_SHORT}/*ifnull*/, + {T_SHORT}/*ifnonnull*/, {T_INT}/*goto_w*/, {T_INT}/*jsr_w*/, + {}/*breakpoint*/, {}, {}, {}, {}, {}, {}, {}, + {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, + {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, + {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, + {}/*impdep1*/, {}/*impdep2*/ + }; + + /** + * Names of opcodes. + */ + public static final String[] OPCODE_NAMES = { + "nop", "aconst_null", "iconst_m1", "iconst_0", "iconst_1", + "iconst_2", "iconst_3", "iconst_4", "iconst_5", "lconst_0", + "lconst_1", "fconst_0", "fconst_1", "fconst_2", "dconst_0", + "dconst_1", "bipush", "sipush", "ldc", "ldc_w", "ldc2_w", "iload", + "lload", "fload", "dload", "aload", "iload_0", "iload_1", "iload_2", + "iload_3", "lload_0", "lload_1", "lload_2", "lload_3", "fload_0", + "fload_1", "fload_2", "fload_3", "dload_0", "dload_1", "dload_2", + "dload_3", "aload_0", "aload_1", "aload_2", "aload_3", "iaload", + "laload", "faload", "daload", "aaload", "baload", "caload", "saload", + "istore", "lstore", "fstore", "dstore", "astore", "istore_0", + "istore_1", "istore_2", "istore_3", "lstore_0", "lstore_1", + "lstore_2", "lstore_3", "fstore_0", "fstore_1", "fstore_2", + "fstore_3", "dstore_0", "dstore_1", "dstore_2", "dstore_3", + "astore_0", "astore_1", "astore_2", "astore_3", "iastore", "lastore", + "fastore", "dastore", "aastore", "bastore", "castore", "sastore", + "pop", "pop2", "dup", "dup_x1", "dup_x2", "dup2", "dup2_x1", + "dup2_x2", "swap", "iadd", "ladd", "fadd", "dadd", "isub", "lsub", + "fsub", "dsub", "imul", "lmul", "fmul", "dmul", "idiv", "ldiv", + "fdiv", "ddiv", "irem", "lrem", "frem", "drem", "ineg", "lneg", + "fneg", "dneg", "ishl", "lshl", "ishr", "lshr", "iushr", "lushr", + "iand", "land", "ior", "lor", "ixor", "lxor", "iinc", "i2l", "i2f", + "i2d", "l2i", "l2f", "l2d", "f2i", "f2l", "f2d", "d2i", "d2l", "d2f", + "i2b", "i2c", "i2s", "lcmp", "fcmpl", "fcmpg", + "dcmpl", "dcmpg", "ifeq", "ifne", "iflt", "ifge", "ifgt", "ifle", + "if_icmpeq", "if_icmpne", "if_icmplt", "if_icmpge", "if_icmpgt", + "if_icmple", "if_acmpeq", "if_acmpne", "goto", "jsr", "ret", + "tableswitch", "lookupswitch", "ireturn", "lreturn", "freturn", + "dreturn", "areturn", "return", "getstatic", "putstatic", "getfield", + "putfield", "invokevirtual", "invokespecial", "invokestatic", + "invokeinterface", ILLEGAL_OPCODE, "new", "newarray", "anewarray", + "arraylength", "athrow", "checkcast", "instanceof", "monitorenter", + "monitorexit", "wide", "multianewarray", "ifnull", "ifnonnull", + "goto_w", "jsr_w", "breakpoint", ILLEGAL_OPCODE, ILLEGAL_OPCODE, + ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, + ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, + ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, + ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, + ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, + ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, + ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, + ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, + ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, + ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, + ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, + ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, ILLEGAL_OPCODE, + ILLEGAL_OPCODE, "impdep1", "impdep2" + }; + + /** + * Number of words consumed on operand stack by instructions. + */ + public static final int[] CONSUME_STACK = { + 0/*nop*/, 0/*aconst_null*/, 0/*iconst_m1*/, 0/*iconst_0*/, 0/*iconst_1*/, + 0/*iconst_2*/, 0/*iconst_3*/, 0/*iconst_4*/, 0/*iconst_5*/, 0/*lconst_0*/, + 0/*lconst_1*/, 0/*fconst_0*/, 0/*fconst_1*/, 0/*fconst_2*/, 0/*dconst_0*/, + 0/*dconst_1*/, 0/*bipush*/, 0/*sipush*/, 0/*ldc*/, 0/*ldc_w*/, 0/*ldc2_w*/, 0/*iload*/, + 0/*lload*/, 0/*fload*/, 0/*dload*/, 0/*aload*/, 0/*iload_0*/, 0/*iload_1*/, 0/*iload_2*/, + 0/*iload_3*/, 0/*lload_0*/, 0/*lload_1*/, 0/*lload_2*/, 0/*lload_3*/, 0/*fload_0*/, + 0/*fload_1*/, 0/*fload_2*/, 0/*fload_3*/, 0/*dload_0*/, 0/*dload_1*/, 0/*dload_2*/, + 0/*dload_3*/, 0/*aload_0*/, 0/*aload_1*/, 0/*aload_2*/, 0/*aload_3*/, 2/*iaload*/, + 2/*laload*/, 2/*faload*/, 2/*daload*/, 2/*aaload*/, 2/*baload*/, 2/*caload*/, 2/*saload*/, + 1/*istore*/, 2/*lstore*/, 1/*fstore*/, 2/*dstore*/, 1/*astore*/, 1/*istore_0*/, + 1/*istore_1*/, 1/*istore_2*/, 1/*istore_3*/, 2/*lstore_0*/, 2/*lstore_1*/, + 2/*lstore_2*/, 2/*lstore_3*/, 1/*fstore_0*/, 1/*fstore_1*/, 1/*fstore_2*/, + 1/*fstore_3*/, 2/*dstore_0*/, 2/*dstore_1*/, 2/*dstore_2*/, 2/*dstore_3*/, + 1/*astore_0*/, 1/*astore_1*/, 1/*astore_2*/, 1/*astore_3*/, 3/*iastore*/, 4/*lastore*/, + 3/*fastore*/, 4/*dastore*/, 3/*aastore*/, 3/*bastore*/, 3/*castore*/, 3/*sastore*/, + 1/*pop*/, 2/*pop2*/, 1/*dup*/, 2/*dup_x1*/, 3/*dup_x2*/, 2/*dup2*/, 3/*dup2_x1*/, + 4/*dup2_x2*/, 2/*swap*/, 2/*iadd*/, 4/*ladd*/, 2/*fadd*/, 4/*dadd*/, 2/*isub*/, 4/*lsub*/, + 2/*fsub*/, 4/*dsub*/, 2/*imul*/, 4/*lmul*/, 2/*fmul*/, 4/*dmul*/, 2/*idiv*/, 4/*ldiv*/, + 2/*fdiv*/, 4/*ddiv*/, 2/*irem*/, 4/*lrem*/, 2/*frem*/, 4/*drem*/, 1/*ineg*/, 2/*lneg*/, + 1/*fneg*/, 2/*dneg*/, 2/*ishl*/, 3/*lshl*/, 2/*ishr*/, 3/*lshr*/, 2/*iushr*/, 3/*lushr*/, + 2/*iand*/, 4/*land*/, 2/*ior*/, 4/*lor*/, 2/*ixor*/, 4/*lxor*/, 0/*iinc*/, + 1/*i2l*/, 1/*i2f*/, 1/*i2d*/, 2/*l2i*/, 2/*l2f*/, 2/*l2d*/, 1/*f2i*/, 1/*f2l*/, + 1/*f2d*/, 2/*d2i*/, 2/*d2l*/, 2/*d2f*/, 1/*i2b*/, 1/*i2c*/, 1/*i2s*/, + 4/*lcmp*/, 2/*fcmpl*/, 2/*fcmpg*/, 4/*dcmpl*/, 4/*dcmpg*/, 1/*ifeq*/, 1/*ifne*/, + 1/*iflt*/, 1/*ifge*/, 1/*ifgt*/, 1/*ifle*/, 2/*if_icmpeq*/, 2/*if_icmpne*/, 2/*if_icmplt*/, + 2 /*if_icmpge*/, 2/*if_icmpgt*/, 2/*if_icmple*/, 2/*if_acmpeq*/, 2/*if_acmpne*/, + 0/*goto*/, 0/*jsr*/, 0/*ret*/, 1/*tableswitch*/, 1/*lookupswitch*/, 1/*ireturn*/, + 2/*lreturn*/, 1/*freturn*/, 2/*dreturn*/, 1/*areturn*/, 0/*return*/, 0/*getstatic*/, + UNPREDICTABLE/*putstatic*/, 1/*getfield*/, UNPREDICTABLE/*putfield*/, + UNPREDICTABLE/*invokevirtual*/, UNPREDICTABLE/*invokespecial*/, + UNPREDICTABLE/*invokestatic*/, + UNPREDICTABLE/*invokeinterface*/, UNDEFINED, 0/*new*/, 1/*newarray*/, 1/*anewarray*/, + 1/*arraylength*/, 1/*athrow*/, 1/*checkcast*/, 1/*instanceof*/, 1/*monitorenter*/, + 1/*monitorexit*/, 0/*wide*/, UNPREDICTABLE/*multianewarray*/, 1/*ifnull*/, 1/*ifnonnull*/, + 0/*goto_w*/, 0/*jsr_w*/, 0/*breakpoint*/, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNPREDICTABLE/*impdep1*/, UNPREDICTABLE/*impdep2*/ + }; + + /** + * Number of words produced onto operand stack by instructions. + */ + public static final int[] PRODUCE_STACK = { + 0/*nop*/, 1/*aconst_null*/, 1/*iconst_m1*/, 1/*iconst_0*/, 1/*iconst_1*/, + 1/*iconst_2*/, 1/*iconst_3*/, 1/*iconst_4*/, 1/*iconst_5*/, 2/*lconst_0*/, + 2/*lconst_1*/, 1/*fconst_0*/, 1/*fconst_1*/, 1/*fconst_2*/, 2/*dconst_0*/, + 2/*dconst_1*/, 1/*bipush*/, 1/*sipush*/, 1/*ldc*/, 1/*ldc_w*/, 2/*ldc2_w*/, 1/*iload*/, + 2/*lload*/, 1/*fload*/, 2/*dload*/, 1/*aload*/, 1/*iload_0*/, 1/*iload_1*/, 1/*iload_2*/, + 1/*iload_3*/, 2/*lload_0*/, 2/*lload_1*/, 2/*lload_2*/, 2/*lload_3*/, 1/*fload_0*/, + 1/*fload_1*/, 1/*fload_2*/, 1/*fload_3*/, 2/*dload_0*/, 2/*dload_1*/, 2/*dload_2*/, + 2/*dload_3*/, 1/*aload_0*/, 1/*aload_1*/, 1/*aload_2*/, 1/*aload_3*/, 1/*iaload*/, + 2/*laload*/, 1/*faload*/, 2/*daload*/, 1/*aaload*/, 1/*baload*/, 1/*caload*/, 1/*saload*/, + 0/*istore*/, 0/*lstore*/, 0/*fstore*/, 0/*dstore*/, 0/*astore*/, 0/*istore_0*/, + 0/*istore_1*/, 0/*istore_2*/, 0/*istore_3*/, 0/*lstore_0*/, 0/*lstore_1*/, + 0/*lstore_2*/, 0/*lstore_3*/, 0/*fstore_0*/, 0/*fstore_1*/, 0/*fstore_2*/, + 0/*fstore_3*/, 0/*dstore_0*/, 0/*dstore_1*/, 0/*dstore_2*/, 0/*dstore_3*/, + 0/*astore_0*/, 0/*astore_1*/, 0/*astore_2*/, 0/*astore_3*/, 0/*iastore*/, 0/*lastore*/, + 0/*fastore*/, 0/*dastore*/, 0/*aastore*/, 0/*bastore*/, 0/*castore*/, 0/*sastore*/, + 0/*pop*/, 0/*pop2*/, 2/*dup*/, 3/*dup_x1*/, 4/*dup_x2*/, 4/*dup2*/, 5/*dup2_x1*/, + 6/*dup2_x2*/, 2/*swap*/, 1/*iadd*/, 2/*ladd*/, 1/*fadd*/, 2/*dadd*/, 1/*isub*/, 2/*lsub*/, + 1/*fsub*/, 2/*dsub*/, 1/*imul*/, 2/*lmul*/, 1/*fmul*/, 2/*dmul*/, 1/*idiv*/, 2/*ldiv*/, + 1/*fdiv*/, 2/*ddiv*/, 1/*irem*/, 2/*lrem*/, 1/*frem*/, 2/*drem*/, 1/*ineg*/, 2/*lneg*/, + 1/*fneg*/, 2/*dneg*/, 1/*ishl*/, 2/*lshl*/, 1/*ishr*/, 2/*lshr*/, 1/*iushr*/, 2/*lushr*/, + 1/*iand*/, 2/*land*/, 1/*ior*/, 2/*lor*/, 1/*ixor*/, 2/*lxor*/, + 0/*iinc*/, 2/*i2l*/, 1/*i2f*/, 2/*i2d*/, 1/*l2i*/, 1/*l2f*/, 2/*l2d*/, 1/*f2i*/, + 2/*f2l*/, 2/*f2d*/, 1/*d2i*/, 2/*d2l*/, 1/*d2f*/, + 1/*i2b*/, 1/*i2c*/, 1/*i2s*/, 1/*lcmp*/, 1/*fcmpl*/, 1/*fcmpg*/, + 1/*dcmpl*/, 1/*dcmpg*/, 0/*ifeq*/, 0/*ifne*/, 0/*iflt*/, 0/*ifge*/, 0/*ifgt*/, 0/*ifle*/, + 0/*if_icmpeq*/, 0/*if_icmpne*/, 0/*if_icmplt*/, 0/*if_icmpge*/, 0/*if_icmpgt*/, + 0/*if_icmple*/, 0/*if_acmpeq*/, 0/*if_acmpne*/, 0/*goto*/, 1/*jsr*/, 0/*ret*/, + 0/*tableswitch*/, 0/*lookupswitch*/, 0/*ireturn*/, 0/*lreturn*/, 0/*freturn*/, + 0/*dreturn*/, 0/*areturn*/, 0/*return*/, UNPREDICTABLE/*getstatic*/, 0/*putstatic*/, + UNPREDICTABLE/*getfield*/, 0/*putfield*/, UNPREDICTABLE/*invokevirtual*/, + UNPREDICTABLE/*invokespecial*/, UNPREDICTABLE/*invokestatic*/, + UNPREDICTABLE/*invokeinterface*/, UNDEFINED, 1/*new*/, 1/*newarray*/, 1/*anewarray*/, + 1/*arraylength*/, 1/*athrow*/, 1/*checkcast*/, 1/*instanceof*/, 0/*monitorenter*/, + 0/*monitorexit*/, 0/*wide*/, 1/*multianewarray*/, 0/*ifnull*/, 0/*ifnonnull*/, + 0/*goto_w*/, 1/*jsr_w*/, 0/*breakpoint*/, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, + UNDEFINED, UNPREDICTABLE/*impdep1*/, UNPREDICTABLE/*impdep2*/ + }; + + /** Attributes and their corresponding names. + */ + public static final byte ATTR_UNKNOWN = -1; + public static final byte ATTR_SOURCE_FILE = 0; + public static final byte ATTR_CONSTANT_VALUE = 1; + public static final byte ATTR_CODE = 2; + public static final byte ATTR_EXCEPTIONS = 3; + public static final byte ATTR_LINE_NUMBER_TABLE = 4; + public static final byte ATTR_LOCAL_VARIABLE_TABLE = 5; + public static final byte ATTR_INNER_CLASSES = 6; + public static final byte ATTR_SYNTHETIC = 7; + public static final byte ATTR_DEPRECATED = 8; + public static final byte ATTR_PMG = 9; + public static final byte ATTR_SIGNATURE = 10; + public static final byte ATTR_STACK_MAP = 11; + + public static final short KNOWN_ATTRIBUTES = 12; + + public static final String[] ATTRIBUTE_NAMES = { + "SourceFile", "ConstantValue", "Code", "Exceptions", + "LineNumberTable", "LocalVariableTable", + "InnerClasses", "Synthetic", "Deprecated", + "PMGClass", "Signature", "StackMap" + }; + + /** Constants used in the StackMap attribute. + */ + public static final byte ITEM_Bogus = 0; + public static final byte ITEM_Integer = 1; + public static final byte ITEM_Float = 2; + public static final byte ITEM_Double = 3; + public static final byte ITEM_Long = 4; + public static final byte ITEM_Null = 5; + public static final byte ITEM_InitObject = 6; + public static final byte ITEM_Object = 7; + public static final byte ITEM_NewObject = 8; + + public static final String[] ITEM_NAMES = { + "Bogus", "Integer", "Float", "Double", "Long", + "Null", "InitObject", "Object", "NewObject" + }; +} diff --git a/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/ExceptionConstants.java b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/ExceptionConstants.java new file mode 100644 index 00000000000..8fd320424f1 --- /dev/null +++ b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/ExceptionConstants.java @@ -0,0 +1,126 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +package com.sun.org.apache.bcel.internal; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +/** + * Exception constants. + * + * @author E. Haase + */ +public interface ExceptionConstants { + /** The mother of all exceptions + */ + public static final Class THROWABLE = Throwable.class; + + /** Super class of any run-time exception + */ + public static final Class RUNTIME_EXCEPTION = RuntimeException.class; + + /** Super class of any linking exception (aka Linkage Error) + */ + public static final Class LINKING_EXCEPTION = LinkageError.class; + + /** Linking Exceptions + */ + public static final Class CLASS_CIRCULARITY_ERROR = ClassCircularityError.class; + public static final Class CLASS_FORMAT_ERROR = ClassFormatError.class; + public static final Class EXCEPTION_IN_INITIALIZER_ERROR = ExceptionInInitializerError.class; + public static final Class INCOMPATIBLE_CLASS_CHANGE_ERROR = IncompatibleClassChangeError.class; + public static final Class ABSTRACT_METHOD_ERROR = AbstractMethodError.class; + public static final Class ILLEGAL_ACCESS_ERROR = IllegalAccessError.class; + public static final Class INSTANTIATION_ERROR = InstantiationError.class; + public static final Class NO_SUCH_FIELD_ERROR = NoSuchFieldError.class; + public static final Class NO_SUCH_METHOD_ERROR = NoSuchMethodError.class; + public static final Class NO_CLASS_DEF_FOUND_ERROR = NoClassDefFoundError.class; + public static final Class UNSATISFIED_LINK_ERROR = UnsatisfiedLinkError.class; + public static final Class VERIFY_ERROR = VerifyError.class; + + /* UnsupportedClassVersionError is new in JDK 1.2 */ + //public static final Class UnsupportedClassVersionError = UnsupportedClassVersionError.class; + + /** Run-Time Exceptions + */ + public static final Class NULL_POINTER_EXCEPTION = NullPointerException.class; + public static final Class ARRAY_INDEX_OUT_OF_BOUNDS_EXCEPTION = ArrayIndexOutOfBoundsException.class; + public static final Class ARITHMETIC_EXCEPTION = ArithmeticException.class; + public static final Class NEGATIVE_ARRAY_SIZE_EXCEPTION = NegativeArraySizeException.class; + public static final Class CLASS_CAST_EXCEPTION = ClassCastException.class; + public static final Class ILLEGAL_MONITOR_STATE = IllegalMonitorStateException.class; + + /** Pre-defined exception arrays according to chapters 5.1-5.4 of the Java Virtual + * Machine Specification + */ + public static final Class[] EXCS_CLASS_AND_INTERFACE_RESOLUTION = { + NO_CLASS_DEF_FOUND_ERROR, CLASS_FORMAT_ERROR, VERIFY_ERROR, ABSTRACT_METHOD_ERROR, + EXCEPTION_IN_INITIALIZER_ERROR, ILLEGAL_ACCESS_ERROR + }; // Chapter 5.1 + + public static final Class[] EXCS_FIELD_AND_METHOD_RESOLUTION = { + NO_SUCH_FIELD_ERROR, ILLEGAL_ACCESS_ERROR, NO_SUCH_METHOD_ERROR + }; // Chapter 5.2 + + public static final Class[] EXCS_INTERFACE_METHOD_RESOLUTION = new Class[0]; // Chapter 5.3 (as below) + public static final Class[] EXCS_STRING_RESOLUTION = new Class[0]; + // Chapter 5.4 (no errors but the ones that _always_ could happen! How stupid.) + + public static final Class[] EXCS_ARRAY_EXCEPTION = { + NULL_POINTER_EXCEPTION, ARRAY_INDEX_OUT_OF_BOUNDS_EXCEPTION + }; + +} diff --git a/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/Repository.java b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/Repository.java new file mode 100644 index 00000000000..ca7c65add3b --- /dev/null +++ b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/Repository.java @@ -0,0 +1,250 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +package com.sun.org.apache.bcel.internal; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import com.sun.org.apache.bcel.internal.classfile.JavaClass; +import com.sun.org.apache.bcel.internal.util.*; +import java.io.*; + +/** + * The repository maintains informations about class interdependencies, e.g., + * whether a class is a sub-class of another. Delegates actual class loading + * to SyntheticRepository with current class path by default. + * + * @see com.sun.org.apache.bcel.internal.util.Repository + * @see com.sun.org.apache.bcel.internal.util.SyntheticRepository + * + * @author M. Dahm + */ +public abstract class Repository { + private static com.sun.org.apache.bcel.internal.util.Repository _repository = + SyntheticRepository.getInstance(); + + /** @return currently used repository instance + */ + public static com.sun.org.apache.bcel.internal.util.Repository getRepository() { + return _repository; + } + + /** Set repository instance to be used for class loading + */ + public static void setRepository(com.sun.org.apache.bcel.internal.util.Repository rep) { + _repository = rep; + } + + /** Lookup class somewhere found on your CLASSPATH, or whereever the + * repository instance looks for it. + * + * @return class object for given fully qualified class name, or null + * if the class could not be found or parsed correctly + */ + public static JavaClass lookupClass(String class_name) { + try { + JavaClass clazz = _repository.findClass(class_name); + + if(clazz == null) { + return _repository.loadClass(class_name); + } else { + return clazz; + } + } catch(ClassNotFoundException ex) { return null; } + } + + /** + * Try to find class source via getResourceAsStream(). + * @see Class + * @return JavaClass object for given runtime class + */ + public static JavaClass lookupClass(Class clazz) { + try { + return _repository.loadClass(clazz); + } catch(ClassNotFoundException ex) { return null; } + } + + /** @return class file object for given Java class. + */ + public static ClassPath.ClassFile lookupClassFile(String class_name) { + try { + return ClassPath.SYSTEM_CLASS_PATH.getClassFile(class_name); + } catch(IOException e) { return null; } + } + + /** Clear the repository. + */ + public static void clearCache() { + _repository.clear(); + } + + /** + * Add clazz to repository if there isn't an equally named class already in there. + * + * @return old entry in repository + */ + public static JavaClass addClass(JavaClass clazz) { + JavaClass old = _repository.findClass(clazz.getClassName()); + _repository.storeClass(clazz); + return old; + } + + /** + * Remove class with given (fully qualified) name from repository. + */ + public static void removeClass(String clazz) { + _repository.removeClass(_repository.findClass(clazz)); + } + + /** + * Remove given class from repository. + */ + public static void removeClass(JavaClass clazz) { + _repository.removeClass(clazz); + } + + /** + * @return list of super classes of clazz in ascending order, i.e., + * Object is always the last element + */ + public static JavaClass[] getSuperClasses(JavaClass clazz) { + return clazz.getSuperClasses(); + } + + /** + * @return list of super classes of clazz in ascending order, i.e., + * Object is always the last element. return "null", if class + * cannot be found. + */ + public static JavaClass[] getSuperClasses(String class_name) { + JavaClass jc = lookupClass(class_name); + return (jc == null? null : getSuperClasses(jc)); + } + + /** + * @return all interfaces implemented by class and its super + * classes and the interfaces that those interfaces extend, and so on. + * (Some people call this a transitive hull). + */ + public static JavaClass[] getInterfaces(JavaClass clazz) { + return clazz.getAllInterfaces(); + } + + /** + * @return all interfaces implemented by class and its super + * classes and the interfaces that extend those interfaces, and so on + */ + public static JavaClass[] getInterfaces(String class_name) { + return getInterfaces(lookupClass(class_name)); + } + + /** + * Equivalent to runtime "instanceof" operator. + * @return true, if clazz is an instance of super_class + */ + public static boolean instanceOf(JavaClass clazz, JavaClass super_class) { + return clazz.instanceOf(super_class); + } + + /** + * @return true, if clazz is an instance of super_class + */ + public static boolean instanceOf(String clazz, String super_class) { + return instanceOf(lookupClass(clazz), lookupClass(super_class)); + } + + /** + * @return true, if clazz is an instance of super_class + */ + public static boolean instanceOf(JavaClass clazz, String super_class) { + return instanceOf(clazz, lookupClass(super_class)); + } + + /** + * @return true, if clazz is an instance of super_class + */ + public static boolean instanceOf(String clazz, JavaClass super_class) { + return instanceOf(lookupClass(clazz), super_class); + } + + /** + * @return true, if clazz is an implementation of interface inter + */ + public static boolean implementationOf(JavaClass clazz, JavaClass inter) { + return clazz.implementationOf(inter); + } + + /** + * @return true, if clazz is an implementation of interface inter + */ + public static boolean implementationOf(String clazz, String inter) { + return implementationOf(lookupClass(clazz), lookupClass(inter)); + } + + /** + * @return true, if clazz is an implementation of interface inter + */ + public static boolean implementationOf(JavaClass clazz, String inter) { + return implementationOf(clazz, lookupClass(inter)); + } + + /** + * @return true, if clazz is an implementation of interface inter + */ + public static boolean implementationOf(String clazz, JavaClass inter) { + return implementationOf(lookupClass(clazz), inter); + } +} diff --git a/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/AccessFlags.java b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/AccessFlags.java new file mode 100644 index 00000000000..ad50a97b501 --- /dev/null +++ b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/AccessFlags.java @@ -0,0 +1,174 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +package com.sun.org.apache.bcel.internal.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import com.sun.org.apache.bcel.internal.Constants; + +/** + * Super class for all objects that have modifiers like private, final, ... + * I.e. classes, fields, and methods. + * + * @author M. Dahm + */ +public abstract class AccessFlags implements java.io.Serializable { + protected int access_flags; + + public AccessFlags() {} + + /** + * @param a inital access flags + */ + public AccessFlags(int a) { + access_flags = a; + } + + /** + * @return Access flags of the object aka. "modifiers". + */ + public final int getAccessFlags() { return access_flags; } + + /** + * @return Access flags of the object aka. "modifiers". + */ + public final int getModifiers() { return access_flags; } + + /** Set access flags aka "modifiers". + * @param access_flags Access flags of the object. + */ + public final void setAccessFlags(int access_flags) { + this.access_flags = access_flags; + } + + /** Set access flags aka "modifiers". + * @param access_flags Access flags of the object. + */ + public final void setModifiers(int access_flags) { + setAccessFlags(access_flags); + } + + private final void setFlag(int flag, boolean set) { + if((access_flags & flag) != 0) { // Flag is set already + if(!set) // Delete flag ? + access_flags ^= flag; + } else { // Flag not set + if(set) // Set flag ? + access_flags |= flag; + } + } + + public final void isPublic(boolean flag) { setFlag(Constants.ACC_PUBLIC, flag); } + public final boolean isPublic() { + return (access_flags & Constants.ACC_PUBLIC) != 0; + } + + public final void isPrivate(boolean flag) { setFlag(Constants.ACC_PRIVATE, flag); } + public final boolean isPrivate() { + return (access_flags & Constants.ACC_PRIVATE) != 0; + } + + public final void isProtected(boolean flag) { setFlag(Constants.ACC_PROTECTED, flag); } + public final boolean isProtected() { + return (access_flags & Constants.ACC_PROTECTED) != 0; + } + + public final void isStatic(boolean flag) { setFlag(Constants.ACC_STATIC, flag); } + public final boolean isStatic() { + return (access_flags & Constants.ACC_STATIC) != 0; + } + + public final void isFinal(boolean flag) { setFlag(Constants.ACC_FINAL, flag); } + public final boolean isFinal() { + return (access_flags & Constants.ACC_FINAL) != 0; + } + + public final void isSynchronized(boolean flag) { setFlag(Constants.ACC_SYNCHRONIZED, flag); } + public final boolean isSynchronized() { + return (access_flags & Constants.ACC_SYNCHRONIZED) != 0; + } + + public final void isVolatile(boolean flag) { setFlag(Constants.ACC_VOLATILE, flag); } + public final boolean isVolatile() { + return (access_flags & Constants.ACC_VOLATILE) != 0; + } + + public final void isTransient(boolean flag) { setFlag(Constants.ACC_TRANSIENT, flag); } + public final boolean isTransient() { + return (access_flags & Constants.ACC_TRANSIENT) != 0; + } + + public final void isNative(boolean flag) { setFlag(Constants.ACC_NATIVE, flag); } + public final boolean isNative() { + return (access_flags & Constants.ACC_NATIVE) != 0; + } + + public final void isInterface(boolean flag) { setFlag(Constants.ACC_INTERFACE, flag); } + public final boolean isInterface() { + return (access_flags & Constants.ACC_INTERFACE) != 0; + } + + public final void isAbstract(boolean flag) { setFlag(Constants.ACC_ABSTRACT, flag); } + public final boolean isAbstract() { + return (access_flags & Constants.ACC_ABSTRACT) != 0; + } + + public final void isStrictfp(boolean flag) { setFlag(Constants.ACC_STRICT, flag); } + public final boolean isStrictfp() { + return (access_flags & Constants.ACC_STRICT) != 0; + } +} diff --git a/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/Attribute.java b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/Attribute.java new file mode 100644 index 00000000000..a391d4d639a --- /dev/null +++ b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/Attribute.java @@ -0,0 +1,305 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +package com.sun.org.apache.bcel.internal.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import com.sun.org.apache.bcel.internal.Constants; +import java.io.*; +import java.util.HashMap; + +/** + * Abstract super class for Attribute objects. Currently the + * ConstantValue, SourceFile, Code, + * Exceptiontable, LineNumberTable, + * LocalVariableTable, InnerClasses and + * Synthetic attributes are supported. The + * Unknown attribute stands for non-standard-attributes. + * + * @author M. Dahm + * @see ConstantValue + * @see SourceFile + * @see Code + * @see Unknown + * @see ExceptionTable + * @see LineNumberTable + * @see LocalVariableTable + * @see InnerClasses + * @see Synthetic + * @see Deprecated + * @see Signature +*/ +public abstract class Attribute implements Cloneable, Node, Serializable { + protected int name_index; // Points to attribute name in constant pool + protected int length; // Content length of attribute field + protected byte tag; // Tag to distiguish subclasses + protected ConstantPool constant_pool; + + protected Attribute(byte tag, int name_index, int length, + ConstantPool constant_pool) { + this.tag = tag; + this.name_index = name_index; + this.length = length; + this.constant_pool = constant_pool; + } + + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + public abstract void accept(Visitor v); + + /** + * Dump attribute to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + public void dump(DataOutputStream file) throws IOException + { + file.writeShort(name_index); + file.writeInt(length); + } + + private static HashMap readers = new HashMap(); + + /** Add an Attribute reader capable of parsing (user-defined) attributes + * named "name". You should not add readers for the standard attributes + * such as "LineNumberTable", because those are handled internally. + * + * @param name the name of the attribute as stored in the class file + * @param r the reader object + */ + public static void addAttributeReader(String name, AttributeReader r) { + readers.put(name, r); + } + + /** Remove attribute reader + * + * @param name the name of the attribute as stored in the class file + */ + public static void removeAttributeReader(String name) { + readers.remove(name); + } + + /* Class method reads one attribute from the input data stream. + * This method must not be accessible from the outside. It is + * called by the Field and Method constructor methods. + * + * @see Field + * @see Method + * @param file Input stream + * @param constant_pool Array of constants + * @return Attribute + * @throws IOException + * @throws ClassFormatException + */ + public static final Attribute readAttribute(DataInputStream file, + ConstantPool constant_pool) + throws IOException, ClassFormatException + { + ConstantUtf8 c; + String name; + int name_index; + int length; + byte tag = Constants.ATTR_UNKNOWN; // Unknown attribute + + // Get class name from constant pool via `name_index' indirection + name_index = (int)file.readUnsignedShort(); + c = (ConstantUtf8)constant_pool.getConstant(name_index, + Constants.CONSTANT_Utf8); + name = c.getBytes(); + + // Length of data in bytes + length = file.readInt(); + + // Compare strings to find known attribute + for(byte i=0; i < Constants.KNOWN_ATTRIBUTES; i++) { + if(name.equals(Constants.ATTRIBUTE_NAMES[i])) { + tag = i; // found! + break; + } + } + + // Call proper constructor, depending on `tag' + switch(tag) { + case Constants.ATTR_UNKNOWN: + AttributeReader r = (AttributeReader)readers.get(name); + + if(r != null) + return r.createAttribute(name_index, length, file, constant_pool); + else + return new Unknown(name_index, length, file, constant_pool); + + case Constants.ATTR_CONSTANT_VALUE: + return new ConstantValue(name_index, length, file, constant_pool); + + case Constants.ATTR_SOURCE_FILE: + return new SourceFile(name_index, length, file, constant_pool); + + case Constants.ATTR_CODE: + return new Code(name_index, length, file, constant_pool); + + case Constants.ATTR_EXCEPTIONS: + return new ExceptionTable(name_index, length, file, constant_pool); + + case Constants.ATTR_LINE_NUMBER_TABLE: + return new LineNumberTable(name_index, length, file, constant_pool); + + case Constants.ATTR_LOCAL_VARIABLE_TABLE: + return new LocalVariableTable(name_index, length, file, constant_pool); + + case Constants.ATTR_INNER_CLASSES: + return new InnerClasses(name_index, length, file, constant_pool); + + case Constants.ATTR_SYNTHETIC: + return new Synthetic(name_index, length, file, constant_pool); + + case Constants.ATTR_DEPRECATED: + return new Deprecated(name_index, length, file, constant_pool); + + case Constants.ATTR_PMG: + return new PMGClass(name_index, length, file, constant_pool); + + case Constants.ATTR_SIGNATURE: + return new Signature(name_index, length, file, constant_pool); + + case Constants.ATTR_STACK_MAP: + return new StackMap(name_index, length, file, constant_pool); + + default: // Never reached + throw new IllegalStateException("Ooops! default case reached."); + } + } + + /** + * @return Length of attribute field in bytes. + */ + public final int getLength() { return length; } + + /** + * @param Attribute length in bytes. + */ + public final void setLength(int length) { + this.length = length; + } + + /** + * @param name_index of attribute. + */ + public final void setNameIndex(int name_index) { + this.name_index = name_index; + } + + /** + * @return Name index in constant pool of attribute name. + */ + public final int getNameIndex() { return name_index; } + + /** + * @return Tag of attribute, i.e., its type. Value may not be altered, thus + * there is no setTag() method. + */ + public final byte getTag() { return tag; } + + /** + * @return Constant pool used by this object. + * @see ConstantPool + */ + public final ConstantPool getConstantPool() { return constant_pool; } + + /** + * @param constant_pool Constant pool to be used for this object. + * @see ConstantPool + */ + public final void setConstantPool(ConstantPool constant_pool) { + this.constant_pool = constant_pool; + } + + /** + * Use copy() if you want to have a deep copy(), i.e., with all references + * copied correctly. + * + * @return shallow copy of this attribute + */ + public Object clone() { + Object o = null; + + try { + o = super.clone(); + } catch(CloneNotSupportedException e) { + e.printStackTrace(); // Never occurs + } + + return o; + } + + /** + * @return deep copy of this attribute + */ + public abstract Attribute copy(ConstantPool constant_pool); + + /** + * @return attribute name. + */ + public String toString() { + return Constants.ATTRIBUTE_NAMES[tag]; + } +} diff --git a/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/AttributeReader.java b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/AttributeReader.java new file mode 100644 index 00000000000..d1f395180aa --- /dev/null +++ b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/AttributeReader.java @@ -0,0 +1,100 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +package com.sun.org.apache.bcel.internal.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +/** + * Unknown (non-standard) attributes may be read via user-defined factory + * objects that can be registered with the Attribute.addAttributeReader + * method. These factory objects should implement this interface. + + * @see Attribute + * @author M. Dahm + */ +public interface AttributeReader { + /** + When this attribute reader is added via the static method + Attribute.addAttributeReader, an attribute name is associated with it. + As the class file parser parses attributes, it will call various + AttributeReaders based on the name of the attributes it is + constructing. + + @param name_index An index into the constant pool, indexing a + ConstantUtf8 that represents the name of the attribute. + + @param length The length of the data contained in the attribute. This + is written into the constant pool and should agree with what the + factory expects the length to be. + + @param file This is the data input stream that the factory needs to read + its data from. + + @param constant_pool This is the constant pool associated with the + Attribute that we are constructing. + + @return The user-defined AttributeReader should take this data and use + it to construct an attribute. In the case of errors, a null can be + returned which will cause the parsing of the class file to fail. + + @see Attribute#addAttributeReader( String, AttributeReader ) + */ + public Attribute createAttribute(int name_index, + int length, + java.io.DataInputStream file, + ConstantPool constant_pool); +} diff --git a/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/ClassFormatException.java b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/ClassFormatException.java new file mode 100644 index 00000000000..203faf3c101 --- /dev/null +++ b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/ClassFormatException.java @@ -0,0 +1,71 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +package com.sun.org.apache.bcel.internal.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +/** + * Thrown when the BCEL attempts to read a class file and determines + * that the file is malformed or otherwise cannot be interpreted as a + * class file. + * + * @author M. Dahm + */ +public class ClassFormatException extends RuntimeException { + public ClassFormatException() { super(); } + public ClassFormatException(String s) { super(s); } +} diff --git a/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/ClassParser.java b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/ClassParser.java new file mode 100644 index 00000000000..d8f32fc5a43 --- /dev/null +++ b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/ClassParser.java @@ -0,0 +1,331 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +package com.sun.org.apache.bcel.internal.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import com.sun.org.apache.bcel.internal.Constants; +import java.io.*; +import java.util.zip.*; + +/** + * Wrapper class that parses a given Java .class file. The method parse returns a + * JavaClass object on success. When an I/O error or an + * inconsistency occurs an appropiate exception is propagated back to + * the caller. + * + * The structure and the names comply, except for a few conveniences, + * exactly with the + * JVM specification 1.0. See this paper for + * further details about the structure of a bytecode file. + * + * @author M. Dahm + */ +public final class ClassParser { + private DataInputStream file; + private ZipFile zip; + private String file_name; + private int class_name_index, superclass_name_index; + private int major, minor; // Compiler version + private int access_flags; // Access rights of parsed class + private int[] interfaces; // Names of implemented interfaces + private ConstantPool constant_pool; // collection of constants + private Field[] fields; // class fields, i.e., its variables + private Method[] methods; // methods defined in the class + private Attribute[] attributes; // attributes defined in the class + private boolean is_zip; // Loaded from zip file + + private static final int BUFSIZE = 8192; + + /** + * Parse class from the given stream. + * + * @param file Input stream + * @param file_name File name + */ + public ClassParser(InputStream file, String file_name) { + this.file_name = file_name; + + String clazz = file.getClass().getName(); // Not a very clean solution ... + is_zip = clazz.startsWith("java.util.zip.") || clazz.startsWith("java.util.jar."); + + if(file instanceof DataInputStream) // Is already a data stream + this.file = (DataInputStream)file; + else + this.file = new DataInputStream(new BufferedInputStream(file, BUFSIZE)); + } + + /** Parse class from given .class file. + * + * @param file_name file name + * @throws IOException + */ + public ClassParser(String file_name) throws IOException + { + is_zip = false; + this.file_name = file_name; + file = new DataInputStream(new BufferedInputStream + (new FileInputStream(file_name), BUFSIZE)); + } + + /** Parse class from given .class file in a ZIP-archive + * + * @param file_name file name + * @throws IOException + */ + public ClassParser(String zip_file, String file_name) throws IOException + { + is_zip = true; + zip = new ZipFile(zip_file); + ZipEntry entry = zip.getEntry(file_name); + + this.file_name = file_name; + + file = new DataInputStream(new BufferedInputStream(zip.getInputStream(entry), + BUFSIZE)); + } + + /** + * Parse the given Java class file and return an object that represents + * the contained data, i.e., constants, methods, fields and commands. + * A ClassFormatException is raised, if the file is not a valid + * .class file. (This does not include verification of the byte code as it + * is performed by the java interpreter). + * + * @return Class object representing the parsed class file + * @throws IOException + * @throws ClassFormatException + */ + public JavaClass parse() throws IOException, ClassFormatException + { + /****************** Read headers ********************************/ + // Check magic tag of class file + readID(); + + // Get compiler version + readVersion(); + + /****************** Read constant pool and related **************/ + // Read constant pool entries + readConstantPool(); + + // Get class information + readClassInfo(); + + // Get interface information, i.e., implemented interfaces + readInterfaces(); + + /****************** Read class fields and methods ***************/ + // Read class fields, i.e., the variables of the class + readFields(); + + // Read class methods, i.e., the functions in the class + readMethods(); + + // Read class attributes + readAttributes(); + + // Check for unknown variables + //Unknown[] u = Unknown.getUnknownAttributes(); + //for(int i=0; i < u.length; i++) + // System.err.println("WARNING: " + u[i]); + + // Everything should have been read now + // if(file.available() > 0) { + // int bytes = file.available(); + // byte[] buf = new byte[bytes]; + // file.read(buf); + + // if(!(is_zip && (buf.length == 1))) { + // System.err.println("WARNING: Trailing garbage at end of " + file_name); + // System.err.println(bytes + " extra bytes: " + Utility.toHexString(buf)); + // } + // } + + // Read everything of interest, so close the file + file.close(); + if(zip != null) + zip.close(); + + // Return the information we have gathered in a new object + return new JavaClass(class_name_index, superclass_name_index, + file_name, major, minor, access_flags, + constant_pool, interfaces, fields, + methods, attributes, is_zip? JavaClass.ZIP : JavaClass.FILE); + } + + /** + * Read information about the attributes of the class. + * @throws IOException + * @throws ClassFormatException + */ + private final void readAttributes() throws IOException, ClassFormatException + { + int attributes_count; + + attributes_count = file.readUnsignedShort(); + attributes = new Attribute[attributes_count]; + + for(int i=0; i < attributes_count; i++) + attributes[i] = Attribute.readAttribute(file, constant_pool); + } + + /** + * Read information about the class and its super class. + * @throws IOException + * @throws ClassFormatException + */ + private final void readClassInfo() throws IOException, ClassFormatException + { + access_flags = file.readUnsignedShort(); + + /* Interfaces are implicitely abstract, the flag should be set + * according to the JVM specification. + */ + if((access_flags & Constants.ACC_INTERFACE) != 0) + access_flags |= Constants.ACC_ABSTRACT; + + if(((access_flags & Constants.ACC_ABSTRACT) != 0) && + ((access_flags & Constants.ACC_FINAL) != 0 )) + throw new ClassFormatException("Class can't be both final and abstract"); + + class_name_index = file.readUnsignedShort(); + superclass_name_index = file.readUnsignedShort(); + } + /** + * Read constant pool entries. + * @throws IOException + * @throws ClassFormatException + */ + private final void readConstantPool() throws IOException, ClassFormatException + { + constant_pool = new ConstantPool(file); + } + + /** + * Read information about the fields of the class, i.e., its variables. + * @throws IOException + * @throws ClassFormatException + */ + private final void readFields() throws IOException, ClassFormatException + { + int fields_count; + + fields_count = file.readUnsignedShort(); + fields = new Field[fields_count]; + + for(int i=0; i < fields_count; i++) + fields[i] = new Field(file, constant_pool); + } + + /******************** Private utility methods **********************/ + + /** + * Check whether the header of the file is ok. + * Of course, this has to be the first action on successive file reads. + * @throws IOException + * @throws ClassFormatException + */ + private final void readID() throws IOException, ClassFormatException + { + int magic = 0xCAFEBABE; + + if(file.readInt() != magic) + throw new ClassFormatException(file_name + " is not a Java .class file"); + } + /** + * Read information about the interfaces implemented by this class. + * @throws IOException + * @throws ClassFormatException + */ + private final void readInterfaces() throws IOException, ClassFormatException + { + int interfaces_count; + + interfaces_count = file.readUnsignedShort(); + interfaces = new int[interfaces_count]; + + for(int i=0; i < interfaces_count; i++) + interfaces[i] = file.readUnsignedShort(); + } + /** + * Read information about the methods of the class. + * @throws IOException + * @throws ClassFormatException + */ + private final void readMethods() throws IOException, ClassFormatException + { + int methods_count; + + methods_count = file.readUnsignedShort(); + methods = new Method[methods_count]; + + for(int i=0; i < methods_count; i++) + methods[i] = new Method(file, constant_pool); + } + /** + * Read major and minor version of compiler which created the file. + * @throws IOException + * @throws ClassFormatException + */ + private final void readVersion() throws IOException, ClassFormatException + { + minor = file.readUnsignedShort(); + major = file.readUnsignedShort(); + } +} diff --git a/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/Code.java b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/Code.java new file mode 100644 index 00000000000..f7ace6f5480 --- /dev/null +++ b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/Code.java @@ -0,0 +1,376 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +package com.sun.org.apache.bcel.internal.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import com.sun.org.apache.bcel.internal.Constants; +import java.io.*; + +/** + * This class represents a chunk of Java byte code contained in a + * method. It is instantiated by the + * Attribute.readAttribute() method. A Code + * attribute contains informations about operand stack, local + * variables, byte code and the exceptions handled within this + * method. + * + * This attribute has attributes itself, namely LineNumberTable which + * is used for debugging purposes and LocalVariableTable which + * contains information about the local variables. + * + * @author M. Dahm + * @see Attribute + * @see CodeException + * @see LineNumberTable + * @see LocalVariableTable + */ +public final class Code extends Attribute { + private int max_stack; // Maximum size of stack used by this method + private int max_locals; // Number of local variables + private int code_length; // Length of code in bytes + private byte[] code; // Actual byte code + + private int exception_table_length; + private CodeException[] exception_table; // Table of handled exceptions + private int attributes_count; // Attributes of code: LineNumber + private Attribute[] attributes; // or LocalVariable + + /** + * Initialize from another object. Note that both objects use the same + * references (shallow copy). Use copy() for a physical copy. + */ + public Code(Code c) { + this(c.getNameIndex(), c.getLength(), c.getMaxStack(), c.getMaxLocals(), + c.getCode(), c.getExceptionTable(), c.getAttributes(), + c.getConstantPool()); + } + + /** + * @param name_index Index pointing to the name Code + * @param length Content length in bytes + * @param file Input stream + * @param constant_pool Array of constants + */ + Code(int name_index, int length, DataInputStream file, + ConstantPool constant_pool) throws IOException + { + // Initialize with some default values which will be overwritten later + this(name_index, length, + file.readUnsignedShort(), file.readUnsignedShort(), + (byte[])null, (CodeException[])null, (Attribute[])null, + constant_pool); + + code_length = file.readInt(); + code = new byte[code_length]; // Read byte code + file.readFully(code); + + /* Read exception table that contains all regions where an exception + * handler is active, i.e., a try { ... } catch() block. + */ + exception_table_length = file.readUnsignedShort(); + exception_table = new CodeException[exception_table_length]; + + for(int i=0; i < exception_table_length; i++) + exception_table[i] = new CodeException(file); + + /* Read all attributes, currently `LineNumberTable' and + * `LocalVariableTable' + */ + attributes_count = file.readUnsignedShort(); + attributes = new Attribute[attributes_count]; + for(int i=0; i < attributes_count; i++) + attributes[i] = Attribute.readAttribute(file, constant_pool); + + /* Adjust length, because of setAttributes in this(), s.b. length + * is incorrect, because it didn't take the internal attributes + * into account yet! Very subtle bug, fixed in 3.1.1. + */ + this.length = length; + } + + /** + * @param name_index Index pointing to the name Code + * @param length Content length in bytes + * @param max_stack Maximum size of stack + * @param max_locals Number of local variables + * @param code Actual byte code + * @param exception_table Table of handled exceptions + * @param attributes Attributes of code: LineNumber or LocalVariable + * @param constant_pool Array of constants + */ + public Code(int name_index, int length, + int max_stack, int max_locals, + byte[] code, + CodeException[] exception_table, + Attribute[] attributes, + ConstantPool constant_pool) + { + super(Constants.ATTR_CODE, name_index, length, constant_pool); + + this.max_stack = max_stack; + this.max_locals = max_locals; + + setCode(code); + setExceptionTable(exception_table); + setAttributes(attributes); // Overwrites length! + } + + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + public void accept(Visitor v) { + v.visitCode(this); + } + + /** + * Dump code attribute to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + public final void dump(DataOutputStream file) throws IOException + { + super.dump(file); + + file.writeShort(max_stack); + file.writeShort(max_locals); + file.writeInt(code_length); + file.write(code, 0, code_length); + + file.writeShort(exception_table_length); + for(int i=0; i < exception_table_length; i++) + exception_table[i].dump(file); + + file.writeShort(attributes_count); + for(int i=0; i < attributes_count; i++) + attributes[i].dump(file); + } + + /** + * @return Collection of code attributes. + * @see Attribute + */ + public final Attribute[] getAttributes() { return attributes; } + + /** + * @return LineNumberTable of Code, if it has one + */ + public LineNumberTable getLineNumberTable() { + for(int i=0; i < attributes_count; i++) + if(attributes[i] instanceof LineNumberTable) + return (LineNumberTable)attributes[i]; + + return null; + } + + /** + * @return LocalVariableTable of Code, if it has one + */ + public LocalVariableTable getLocalVariableTable() { + for(int i=0; i < attributes_count; i++) + if(attributes[i] instanceof LocalVariableTable) + return (LocalVariableTable)attributes[i]; + + return null; + } + + /** + * @return Actual byte code of the method. + */ + public final byte[] getCode() { return code; } + + /** + * @return Table of handled exceptions. + * @see CodeException + */ + public final CodeException[] getExceptionTable() { return exception_table; } + + /** + * @return Number of local variables. + */ + public final int getMaxLocals() { return max_locals; } + + /** + * @return Maximum size of stack used by this method. + */ + + public final int getMaxStack() { return max_stack; } + + /** + * @return the internal length of this code attribute (minus the first 6 bytes) + * and excluding all its attributes + */ + private final int getInternalLength() { + return 2 /*max_stack*/ + 2 /*max_locals*/ + 4 /*code length*/ + + code_length /*byte-code*/ + + 2 /*exception-table length*/ + + 8 * exception_table_length /* exception table */ + + 2 /* attributes count */; + } + + /** + * @return the full size of this code attribute, minus its first 6 bytes, + * including the size of all its contained attributes + */ + private final int calculateLength() { + int len = 0; + + for(int i=0; i < attributes_count; i++) + len += attributes[i].length + 6 /*attribute header size*/; + + return len + getInternalLength(); + } + + /** + * @param attributes. + */ + public final void setAttributes(Attribute[] attributes) { + this.attributes = attributes; + attributes_count = (attributes == null)? 0 : attributes.length; + length = calculateLength(); // Adjust length + } + + /** + * @param code byte code + */ + public final void setCode(byte[] code) { + this.code = code; + code_length = (code == null)? 0 : code.length; + } + + /** + * @param exception_table exception table + */ + public final void setExceptionTable(CodeException[] exception_table) { + this.exception_table = exception_table; + exception_table_length = (exception_table == null)? 0 : + exception_table.length; + } + + /** + * @param max_locals maximum number of local variables + */ + public final void setMaxLocals(int max_locals) { + this.max_locals = max_locals; + } + + /** + * @param max_stack maximum stack size + */ + public final void setMaxStack(int max_stack) { + this.max_stack = max_stack; + } + + /** + * @return String representation of code chunk. + */ + public final String toString(boolean verbose) { + StringBuffer buf; + + buf = new StringBuffer("Code(max_stack = " + max_stack + + ", max_locals = " + max_locals + + ", code_length = " + code_length + ")\n" + + Utility.codeToString(code, constant_pool, 0, -1, verbose)); + + if(exception_table_length > 0) { + buf.append("\nException handler(s) = \n" + "From\tTo\tHandler\tType\n"); + + for(int i=0; i < exception_table_length; i++) + buf.append(exception_table[i].toString(constant_pool, verbose) + "\n"); + } + + if(attributes_count > 0) { + buf.append("\nAttribute(s) = \n"); + + for(int i=0; i < attributes_count; i++) + buf.append(attributes[i].toString() + "\n"); + } + + return buf.toString(); + } + + /** + * @return String representation of code chunk. + */ + public final String toString() { + return toString(true); + } + + /** + * @return deep copy of this attribute + */ + public Attribute copy(ConstantPool constant_pool) { + Code c = (Code)clone(); + c.code = (byte[])code.clone(); + c.constant_pool = constant_pool; + + c.exception_table = new CodeException[exception_table_length]; + for(int i=0; i < exception_table_length; i++) + c.exception_table[i] = exception_table[i].copy(); + + c.attributes = new Attribute[attributes_count]; + for(int i=0; i < attributes_count; i++) + c.attributes[i] = attributes[i].copy(constant_pool); + + return c; + } +} diff --git a/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/CodeException.java b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/CodeException.java new file mode 100644 index 00000000000..4cf1725a9d6 --- /dev/null +++ b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/CodeException.java @@ -0,0 +1,232 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +package com.sun.org.apache.bcel.internal.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import com.sun.org.apache.bcel.internal.Constants; +import java.io.*; + +/** + * This class represents an entry in the exception table of the Code + * attribute and is used only there. It contains a range in which a + * particular exception handler is active. + * + * @author M. Dahm + * @see Code + */ +public final class CodeException + implements Cloneable, Constants, Node, Serializable +{ + private int start_pc; // Range in the code the exception handler is + private int end_pc; // active. start_pc is inclusive, end_pc exclusive + private int handler_pc; /* Starting address of exception handler, i.e., + * an offset from start of code. + */ + private int catch_type; /* If this is zero the handler catches any + * exception, otherwise it points to the + * exception class which is to be caught. + */ + /** + * Initialize from another object. + */ + public CodeException(CodeException c) { + this(c.getStartPC(), c.getEndPC(), c.getHandlerPC(), c.getCatchType()); + } + + /** + * Construct object from file stream. + * @param file Input stream + * @throws IOException + */ + CodeException(DataInputStream file) throws IOException + { + this(file.readUnsignedShort(), file.readUnsignedShort(), + file.readUnsignedShort(), file.readUnsignedShort()); + } + + /** + * @param start_pc Range in the code the exception handler is active, + * start_pc is inclusive while + * @param end_pc is exclusive + * @param handler_pc Starting address of exception handler, i.e., + * an offset from start of code. + * @param catch_type If zero the handler catches any + * exception, otherwise it points to the exception class which is + * to be caught. + */ + public CodeException(int start_pc, int end_pc, int handler_pc, + int catch_type) + { + this.start_pc = start_pc; + this.end_pc = end_pc; + this.handler_pc = handler_pc; + this.catch_type = catch_type; + } + + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + public void accept(Visitor v) { + v.visitCodeException(this); + } + /** + * Dump code exception to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + public final void dump(DataOutputStream file) throws IOException + { + file.writeShort(start_pc); + file.writeShort(end_pc); + file.writeShort(handler_pc); + file.writeShort(catch_type); + } + + /** + * @return 0, if the handler catches any exception, otherwise it points to + * the exception class which is to be caught. + */ + public final int getCatchType() { return catch_type; } + + /** + * @return Exclusive end index of the region where the handler is active. + */ + public final int getEndPC() { return end_pc; } + + /** + * @return Starting address of exception handler, relative to the code. + */ + public final int getHandlerPC() { return handler_pc; } + + /** + * @return Inclusive start index of the region where the handler is active. + */ + public final int getStartPC() { return start_pc; } + + /** + * @param catch_type. + */ + public final void setCatchType(int catch_type) { + this.catch_type = catch_type; + } + + /** + * @param end_pc end of handled block + */ + public final void setEndPC(int end_pc) { + this.end_pc = end_pc; + } + + /** + * @param handler_pc where the actual code is + */ + public final void setHandlerPC(int handler_pc) { + this.handler_pc = handler_pc; + } + + /** + * @param start_pc start of handled block + */ + public final void setStartPC(int start_pc) { + this.start_pc = start_pc; + } + + /** + * @return String representation. + */ + public final String toString() { + return "CodeException(start_pc = " + start_pc + + ", end_pc = " + end_pc + + ", handler_pc = " + handler_pc + ", catch_type = " + catch_type + ")"; + } + + /** + * @return String representation. + */ + public final String toString(ConstantPool cp, boolean verbose) { + String str; + + if(catch_type == 0) + str = "(0)"; + else + str = Utility.compactClassName(cp.getConstantString(catch_type, CONSTANT_Class), false) + + (verbose? "(" + catch_type + ")" : ""); + + return start_pc + "\t" + end_pc + "\t" + handler_pc + "\t" + str; + } + + public final String toString(ConstantPool cp) { + return toString(cp, true); + } + + /** + * @return deep copy of this object + */ + public CodeException copy() { + try { + return (CodeException)clone(); + } catch(CloneNotSupportedException e) {} + + return null; + } +} diff --git a/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/Constant.java b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/Constant.java new file mode 100644 index 00000000000..931b8e27c79 --- /dev/null +++ b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/Constant.java @@ -0,0 +1,151 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +package com.sun.org.apache.bcel.internal.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import com.sun.org.apache.bcel.internal.Constants; +import java.io.*; + +/** + * Abstract superclass for classes to represent the different constant types + * in the constant pool of a class file. The classes keep closely to + * the JVM specification. + * + * @author M. Dahm + */ +public abstract class Constant implements Cloneable, Node, Serializable { + /* In fact this tag is redundant since we can distinguish different + * `Constant' objects by their type, i.e., via `instanceof'. In some + * places we will use the tag for switch()es anyway. + * + * First, we want match the specification as closely as possible. Second we + * need the tag as an index to select the corresponding class name from the + * `CONSTANT_NAMES' array. + */ + protected byte tag; + + Constant(byte tag) { this.tag = tag; } + + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + public abstract void accept(Visitor v); + + public abstract void dump(DataOutputStream file) throws IOException; + + /** + * @return Tag of constant, i.e., its type. No setTag() method to avoid + * confusion. + */ + public final byte getTag() { return tag; } + + /** + * @return String representation. + */ + public String toString() { + return Constants.CONSTANT_NAMES[tag] + "[" + tag + "]"; + } + + /** + * @return deep copy of this constant + */ + public Constant copy() { + try { + return (Constant)super.clone(); + } catch(CloneNotSupportedException e) {} + + return null; + } + + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } + + /** + * Read one constant from the given file, the type depends on a tag byte. + * + * @param file Input stream + * @return Constant object + */ + static final Constant readConstant(DataInputStream file) + throws IOException, ClassFormatException + { + byte b = file.readByte(); // Read tag byte + + switch(b) { + case Constants.CONSTANT_Class: return new ConstantClass(file); + case Constants.CONSTANT_Fieldref: return new ConstantFieldref(file); + case Constants.CONSTANT_Methodref: return new ConstantMethodref(file); + case Constants.CONSTANT_InterfaceMethodref: return new + ConstantInterfaceMethodref(file); + case Constants.CONSTANT_String: return new ConstantString(file); + case Constants.CONSTANT_Integer: return new ConstantInteger(file); + case Constants.CONSTANT_Float: return new ConstantFloat(file); + case Constants.CONSTANT_Long: return new ConstantLong(file); + case Constants.CONSTANT_Double: return new ConstantDouble(file); + case Constants.CONSTANT_NameAndType: return new ConstantNameAndType(file); + case Constants.CONSTANT_Utf8: return new ConstantUtf8(file); + default: + throw new ClassFormatException("Invalid byte tag in constant pool: " + b); + } + } +} diff --git a/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantCP.java b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantCP.java new file mode 100644 index 00000000000..b12d752c2cb --- /dev/null +++ b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantCP.java @@ -0,0 +1,157 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +package com.sun.org.apache.bcel.internal.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +import java.io.*; +import com.sun.org.apache.bcel.internal.Constants; + +/** + * Abstract super class for Fieldref and Methodref constants. + * + * @author M. Dahm + * @see ConstantFieldref + * @see ConstantMethodref + * @see ConstantInterfaceMethodref + */ +public abstract class ConstantCP extends Constant { + /** References to the constants containing the class and the field signature + */ + protected int class_index, name_and_type_index; + + /** + * Initialize from another object. + */ + public ConstantCP(ConstantCP c) { + this(c.getTag(), c.getClassIndex(), c.getNameAndTypeIndex()); + } + + /** + * Initialize instance from file data. + * + * @param tag Constant type tag + * @param file Input stream + * @throws IOException + */ + ConstantCP(byte tag, DataInputStream file) throws IOException + { + this(tag, file.readUnsignedShort(), file.readUnsignedShort()); + } + + /** + * @param class_index Reference to the class containing the field + * @param name_and_type_index and the field signature + */ + protected ConstantCP(byte tag, int class_index, + int name_and_type_index) { + super(tag); + this.class_index = class_index; + this.name_and_type_index = name_and_type_index; + } + + /** + * Dump constant field reference to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + public final void dump(DataOutputStream file) throws IOException + { + file.writeByte(tag); + file.writeShort(class_index); + file.writeShort(name_and_type_index); + } + + /** + * @return Reference (index) to class this field or method belongs to. + */ + public final int getClassIndex() { return class_index; } + + /** + * @return Reference (index) to signature of the field. + */ + public final int getNameAndTypeIndex() { return name_and_type_index; } + + /** + * @param class_index points to Constant_class + */ + public final void setClassIndex(int class_index) { + this.class_index = class_index; + } + + /** + * @return Class this field belongs to. + */ + public String getClass(ConstantPool cp) { + return cp.constantToString(class_index, Constants.CONSTANT_Class); + } + + /** + * @param name_and_type_index points to Constant_NameAndType + */ + public final void setNameAndTypeIndex(int name_and_type_index) { + this.name_and_type_index = name_and_type_index; + } + + /** + * @return String representation. + */ + public final String toString() { + return super.toString() + "(class_index = " + class_index + + ", name_and_type_index = " + name_and_type_index + ")"; + } +} diff --git a/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantClass.java b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantClass.java new file mode 100644 index 00000000000..e047ca88db5 --- /dev/null +++ b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantClass.java @@ -0,0 +1,157 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +package com.sun.org.apache.bcel.internal.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import com.sun.org.apache.bcel.internal.Constants; +import java.io.*; + +/** + * This class is derived from the abstract + * Constant class + * and represents a reference to a (external) class. + * + * @author M. Dahm + * @see Constant + */ +public final class ConstantClass extends Constant implements ConstantObject { + private int name_index; // Identical to ConstantString except for the name + + /** + * Initialize from another object. + */ + public ConstantClass(ConstantClass c) { + this(c.getNameIndex()); + } + + /** + * Initialize instance from file data. + * + * @param file Input stream + * @throws IOException + */ + ConstantClass(DataInputStream file) throws IOException + { + this(file.readUnsignedShort()); + } + + /** + * @param name_index Name index in constant pool. Should refer to a + * ConstantUtf8. + */ + public ConstantClass(int name_index) { + super(Constants.CONSTANT_Class); + this.name_index = name_index; + } + + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + public void accept(Visitor v) { + v.visitConstantClass(this); + } + + /** + * Dump constant class to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + public final void dump(DataOutputStream file) throws IOException + { + file.writeByte(tag); + file.writeShort(name_index); + } + + /** + * @return Name index in constant pool of class name. + */ + public final int getNameIndex() { return name_index; } + + /** + * @param name_index. + */ + public final void setNameIndex(int name_index) { + this.name_index = name_index; + } + + + /** @return String object + */ + public Object getConstantValue(ConstantPool cp) { + Constant c = cp.getConstant(name_index, Constants.CONSTANT_Utf8); + return ((ConstantUtf8)c).getBytes(); + } + + /** @return dereferenced string + */ + public String getBytes(ConstantPool cp) { + return (String)getConstantValue(cp); + } + + /** + * @return String representation. + */ + public final String toString() { + return super.toString() + "(name_index = " + name_index + ")"; + } +} diff --git a/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantDouble.java b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantDouble.java new file mode 100644 index 00000000000..74e7ef8129d --- /dev/null +++ b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantDouble.java @@ -0,0 +1,145 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +package com.sun.org.apache.bcel.internal.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import com.sun.org.apache.bcel.internal.Constants; +import java.io.*; + +/** + * This class is derived from the abstract + * Constant class + * and represents a reference to a Double object. + * + * @author M. Dahm + * @see Constant + */ +public final class ConstantDouble extends Constant implements ConstantObject { + private double bytes; + + /** + * @param bytes Data + */ + public ConstantDouble(double bytes) { + super(Constants.CONSTANT_Double); + this.bytes = bytes; + } + + /** + * Initialize from another object. + */ + public ConstantDouble(ConstantDouble c) { + this(c.getBytes()); + } + + /** + * Initialize instance from file data. + * + * @param file Input stream + * @throws IOException + */ + ConstantDouble(DataInputStream file) throws IOException + { + this(file.readDouble()); + } + + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + public void accept(Visitor v) { + v.visitConstantDouble(this); + } + /** + * Dump constant double to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + public final void dump(DataOutputStream file) throws IOException + { + file.writeByte(tag); + file.writeDouble(bytes); + } + /** + * @return data, i.e., 8 bytes. + */ + public final double getBytes() { return bytes; } + /** + * @param bytes. + */ + public final void setBytes(double bytes) { + this.bytes = bytes; + } + /** + * @return String representation. + */ + public final String toString() + { + return super.toString() + "(bytes = " + bytes + ")"; + } + + /** @return Double object + */ + public Object getConstantValue(ConstantPool cp) { + return new Double(bytes); + } +} diff --git a/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantFieldref.java b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantFieldref.java new file mode 100644 index 00000000000..5d76e11fdd9 --- /dev/null +++ b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantFieldref.java @@ -0,0 +1,107 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +package com.sun.org.apache.bcel.internal.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import com.sun.org.apache.bcel.internal.Constants; +import java.io.*; + +/** + * This class represents a constant pool reference to a field. + * + * @author M. Dahm + */ +public final class ConstantFieldref extends ConstantCP { + /** + * Initialize from another object. + */ + public ConstantFieldref(ConstantFieldref c) { + super(Constants.CONSTANT_Fieldref, c.getClassIndex(), c.getNameAndTypeIndex()); + } + + /** + * Initialize instance from file data. + * + * @param file input stream + * @throws IOException + */ + ConstantFieldref(DataInputStream file) throws IOException + { + super(Constants.CONSTANT_Fieldref, file); + } + + /** + * @param class_index Reference to the class containing the Field + * @param name_and_type_index and the Field signature + */ + public ConstantFieldref(int class_index, + int name_and_type_index) { + super(Constants.CONSTANT_Fieldref, class_index, name_and_type_index); + } + + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of Fields, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + public void accept(Visitor v) { + v.visitConstantFieldref(this); + } +} diff --git a/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantFloat.java b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantFloat.java new file mode 100644 index 00000000000..e18eb14f973 --- /dev/null +++ b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantFloat.java @@ -0,0 +1,144 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +package com.sun.org.apache.bcel.internal.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import com.sun.org.apache.bcel.internal.Constants; +import java.io.*; + +/** + * This class is derived from the abstract + * Constant class + * and represents a reference to a float object. + * + * @author M. Dahm + * @see Constant + */ +public final class ConstantFloat extends Constant implements ConstantObject { + private float bytes; + + /** + * @param bytes Data + */ + public ConstantFloat(float bytes) + { + super(Constants.CONSTANT_Float); + this.bytes = bytes; + } + /** + * Initialize from another object. Note that both objects use the same + * references (shallow copy). Use clone() for a physical copy. + */ + public ConstantFloat(ConstantFloat c) { + this(c.getBytes()); + } + /** + * Initialize instance from file data. + * + * @param file Input stream + * @throws IOException + */ + ConstantFloat(DataInputStream file) throws IOException + { + this(file.readFloat()); + } + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + public void accept(Visitor v) { + v.visitConstantFloat(this); + } + /** + * Dump constant float to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + public final void dump(DataOutputStream file) throws IOException + { + file.writeByte(tag); + file.writeFloat(bytes); + } + /** + * @return data, i.e., 4 bytes. + */ + public final float getBytes() { return bytes; } + /** + * @param bytes. + */ + public final void setBytes(float bytes) { + this.bytes = bytes; + } + + /** + * @return String representation. + */ + public final String toString() { + return super.toString() + "(bytes = " + bytes + ")"; + } + + /** @return Float object + */ + public Object getConstantValue(ConstantPool cp) { + return new Float(bytes); + } +} diff --git a/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantInteger.java b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantInteger.java new file mode 100644 index 00000000000..a1e811e9b5e --- /dev/null +++ b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantInteger.java @@ -0,0 +1,151 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ + +package com.sun.org.apache.bcel.internal.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + + +import com.sun.org.apache.bcel.internal.Constants; +import java.io.*; + +/** + * This class is derived from the abstract + * Constant class + * and represents a reference to an int object. + * + * @author M. Dahm + * @see Constant + */ +public final class ConstantInteger extends Constant implements ConstantObject { + private int bytes; + + /** + * @param bytes Data + */ + public ConstantInteger(int bytes) + { + super(Constants.CONSTANT_Integer); + this.bytes = bytes; + } + + /** + * Initialize from another object. + */ + public ConstantInteger(ConstantInteger c) { + this(c.getBytes()); + } + + /** + * Initialize instance from file data. + * + * @param file Input stream + * @throws IOException + */ + ConstantInteger(DataInputStream file) throws IOException + { + this(file.readInt()); + } + + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + public void accept(Visitor v) { + v.visitConstantInteger(this); + } + + /** + * Dump constant integer to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + public final void dump(DataOutputStream file) throws IOException + { + file.writeByte(tag); + file.writeInt(bytes); + } + + /** + * @return data, i.e., 4 bytes. + */ + public final int getBytes() { return bytes; } + + /** + * @param bytes. + */ + public final void setBytes(int bytes) { + this.bytes = bytes; + } + + /** + * @return String representation. + */ + public final String toString() { + return super.toString() + "(bytes = " + bytes + ")"; + } + + /** @return Integer object + */ + public Object getConstantValue(ConstantPool cp) { + return new Integer(bytes); + } +} diff --git a/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantInterfaceMethodref.java b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantInterfaceMethodref.java new file mode 100644 index 00000000000..46b742651b8 --- /dev/null +++ b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantInterfaceMethodref.java @@ -0,0 +1,107 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +package com.sun.org.apache.bcel.internal.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import com.sun.org.apache.bcel.internal.Constants; +import java.io.*; + +/** + * This class represents a constant pool reference to an interface method. + * + * @author M. Dahm + */ +public final class ConstantInterfaceMethodref extends ConstantCP { + /** + * Initialize from another object. + */ + public ConstantInterfaceMethodref(ConstantInterfaceMethodref c) { + super(Constants.CONSTANT_InterfaceMethodref, c.getClassIndex(), c.getNameAndTypeIndex()); + } + + /** + * Initialize instance from file data. + * + * @param file input stream + * @throws IOException + */ + ConstantInterfaceMethodref(DataInputStream file) throws IOException + { + super(Constants.CONSTANT_InterfaceMethodref, file); + } + + /** + * @param class_index Reference to the class containing the method + * @param name_and_type_index and the method signature + */ + public ConstantInterfaceMethodref(int class_index, + int name_and_type_index) { + super(Constants.CONSTANT_InterfaceMethodref, class_index, name_and_type_index); + } + + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + public void accept(Visitor v) { + v.visitConstantInterfaceMethodref(this); + } +} diff --git a/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantLong.java b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantLong.java new file mode 100644 index 00000000000..e29a7c9c1a3 --- /dev/null +++ b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantLong.java @@ -0,0 +1,142 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +package com.sun.org.apache.bcel.internal.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import com.sun.org.apache.bcel.internal.Constants; +import java.io.*; + +/** + * This class is derived from the abstract + * Constant class + * and represents a reference to a long object. + * + * @author M. Dahm + * @see Constant + */ +public final class ConstantLong extends Constant implements ConstantObject { + private long bytes; + + /** + * @param bytes Data + */ + public ConstantLong(long bytes) + { + super(Constants.CONSTANT_Long); + this.bytes = bytes; + } + /** + * Initialize from another object. + */ + public ConstantLong(ConstantLong c) { + this(c.getBytes()); + } + /** + * Initialize instance from file data. + * + * @param file Input stream + * @throws IOException + */ + ConstantLong(DataInputStream file) throws IOException + { + this(file.readLong()); + } + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + public void accept(Visitor v) { + v.visitConstantLong(this); + } + /** + * Dump constant long to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + public final void dump(DataOutputStream file) throws IOException + { + file.writeByte(tag); + file.writeLong(bytes); + } + /** + * @return data, i.e., 8 bytes. + */ + public final long getBytes() { return bytes; } + /** + * @param bytes. + */ + public final void setBytes(long bytes) { + this.bytes = bytes; + } + /** + * @return String representation. + */ + public final String toString() { + return super.toString() + "(bytes = " + bytes + ")"; + } + + /** @return Long object + */ + public Object getConstantValue(ConstantPool cp) { + return new Long(bytes); + } +} diff --git a/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantMethodref.java b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantMethodref.java new file mode 100644 index 00000000000..044c99be955 --- /dev/null +++ b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantMethodref.java @@ -0,0 +1,107 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +package com.sun.org.apache.bcel.internal.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import com.sun.org.apache.bcel.internal.Constants; +import java.io.*; + +/** + * This class represents a constant pool reference to a method. + * + * @author M. Dahm + */ +public final class ConstantMethodref extends ConstantCP { + /** + * Initialize from another object. + */ + public ConstantMethodref(ConstantMethodref c) { + super(Constants.CONSTANT_Methodref, c.getClassIndex(), c.getNameAndTypeIndex()); + } + + /** + * Initialize instance from file data. + * + * @param file input stream + * @throws IOException + */ + ConstantMethodref(DataInputStream file) throws IOException + { + super(Constants.CONSTANT_Methodref, file); + } + + /** + * @param class_index Reference to the class containing the method + * @param name_and_type_index and the method signature + */ + public ConstantMethodref(int class_index, + int name_and_type_index) { + super(Constants.CONSTANT_Methodref, class_index, name_and_type_index); + } + + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + public void accept(Visitor v) { + v.visitConstantMethodref(this); + } +} diff --git a/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantNameAndType.java b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantNameAndType.java new file mode 100644 index 00000000000..19ad468d7f3 --- /dev/null +++ b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantNameAndType.java @@ -0,0 +1,174 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +package com.sun.org.apache.bcel.internal.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import com.sun.org.apache.bcel.internal.Constants; +import java.io.*; + +/** + * This class is derived from the abstract + * Constant class + * and represents a reference to the name and signature + * of a field or method. + * + * @author M. Dahm + * @see Constant + */ +public final class ConstantNameAndType extends Constant { + private int name_index; // Name of field/method + private int signature_index; // and its signature. + + /** + * Initialize from another object. + */ + public ConstantNameAndType(ConstantNameAndType c) { + this(c.getNameIndex(), c.getSignatureIndex()); + } + + /** + * Initialize instance from file data. + * + * @param file Input stream + * @throws IOException + */ + ConstantNameAndType(DataInputStream file) throws IOException + { + this((int)file.readUnsignedShort(), (int)file.readUnsignedShort()); + } + + /** + * @param name_index Name of field/method + * @param signature_index and its signature + */ + public ConstantNameAndType(int name_index, + int signature_index) + { + super(Constants.CONSTANT_NameAndType); + this.name_index = name_index; + this.signature_index = signature_index; + } + + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + public void accept(Visitor v) { + v.visitConstantNameAndType(this); + } + + /** + * Dump name and signature index to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + public final void dump(DataOutputStream file) throws IOException + { + file.writeByte(tag); + file.writeShort(name_index); + file.writeShort(signature_index); + } + + /** + * @return Name index in constant pool of field/method name. + */ + public final int getNameIndex() { return name_index; } + + /** @return name + */ + public final String getName(ConstantPool cp) { + return cp.constantToString(getNameIndex(), Constants.CONSTANT_Utf8); + } + + /** + * @return Index in constant pool of field/method signature. + */ + public final int getSignatureIndex() { return signature_index; } + + /** @return signature + */ + public final String getSignature(ConstantPool cp) { + return cp.constantToString(getSignatureIndex(), Constants.CONSTANT_Utf8); + } + + /** + * @param name_index. + */ + public final void setNameIndex(int name_index) { + this.name_index = name_index; + } + + /** + * @param signature_index. + */ + public final void setSignatureIndex(int signature_index) { + this.signature_index = signature_index; + } + + /** + * @return String representation + */ + public final String toString() { + return super.toString() + "(name_index = " + name_index + + ", signature_index = " + signature_index + ")"; + } +} diff --git a/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantObject.java b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantObject.java new file mode 100644 index 00000000000..61440e54a5c --- /dev/null +++ b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantObject.java @@ -0,0 +1,72 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +package com.sun.org.apache.bcel.internal.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +/** + * This interface denotes those constants that have a "natural" value, + * such as ConstantLong, ConstantString, etc.. + * + * @author M. Dahm + * @see Constant + */ +public interface ConstantObject { + /** @return object representing the constant, e.g., Long for ConstantLong + */ + public abstract Object getConstantValue(ConstantPool cp); +} diff --git a/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantPool.java b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantPool.java new file mode 100644 index 00000000000..091e70cbfbf --- /dev/null +++ b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantPool.java @@ -0,0 +1,375 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +package com.sun.org.apache.bcel.internal.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import com.sun.org.apache.bcel.internal.Constants; +import java.io.*; + +/** + * This class represents the constant pool, i.e., a table of constants, of + * a parsed classfile. It may contain null references, due to the JVM + * specification that skips an entry after an 8-byte constant (double, + * long) entry. Those interested in generating constant pools + * programatically should see + * ConstantPoolGen. + + * @see Constant + * @see com.sun.org.apache.bcel.internal.generic.ConstantPoolGen + * @author M. Dahm + */ +public class ConstantPool implements Cloneable, Node, Serializable { + private int constant_pool_count; + private Constant[] constant_pool; + + /** + * @param constant_pool Array of constants + */ + public ConstantPool(Constant[] constant_pool) + { + setConstantPool(constant_pool); + } + + /** + * Read constants from given file stream. + * + * @param file Input stream + * @throws IOException + * @throws ClassFormatException + */ + ConstantPool(DataInputStream file) throws IOException, ClassFormatException + { + byte tag; + + constant_pool_count = file.readUnsignedShort(); + constant_pool = new Constant[constant_pool_count]; + + /* constant_pool[0] is unused by the compiler and may be used freely + * by the implementation. + */ + for(int i=1; i < constant_pool_count; i++) { + constant_pool[i] = Constant.readConstant(file); + + /* Quote from the JVM specification: + * "All eight byte constants take up two spots in the constant pool. + * If this is the n'th byte in the constant pool, then the next item + * will be numbered n+2" + * + * Thus we have to increment the index counter. + */ + tag = constant_pool[i].getTag(); + if((tag == Constants.CONSTANT_Double) || (tag == Constants.CONSTANT_Long)) + i++; + } + } + + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + public void accept(Visitor v) { + v.visitConstantPool(this); + } + + /** + * Resolve constant to a string representation. + * + * @param constant Constant to be printed + * @return String representation + */ + public String constantToString(Constant c) + throws ClassFormatException + { + String str; + int i; + byte tag = c.getTag(); + + switch(tag) { + case Constants.CONSTANT_Class: + i = ((ConstantClass)c).getNameIndex(); + c = getConstant(i, Constants.CONSTANT_Utf8); + str = Utility.compactClassName(((ConstantUtf8)c).getBytes(), false); + break; + + case Constants.CONSTANT_String: + i = ((ConstantString)c).getStringIndex(); + c = getConstant(i, Constants.CONSTANT_Utf8); + str = "\"" + escape(((ConstantUtf8)c).getBytes()) + "\""; + break; + + case Constants.CONSTANT_Utf8: str = ((ConstantUtf8)c).getBytes(); break; + case Constants.CONSTANT_Double: str = "" + ((ConstantDouble)c).getBytes(); break; + case Constants.CONSTANT_Float: str = "" + ((ConstantFloat)c).getBytes(); break; + case Constants.CONSTANT_Long: str = "" + ((ConstantLong)c).getBytes(); break; + case Constants.CONSTANT_Integer: str = "" + ((ConstantInteger)c).getBytes(); break; + + case Constants.CONSTANT_NameAndType: + str = (constantToString(((ConstantNameAndType)c).getNameIndex(), + Constants.CONSTANT_Utf8) + " " + + constantToString(((ConstantNameAndType)c).getSignatureIndex(), + Constants.CONSTANT_Utf8)); + break; + + case Constants.CONSTANT_InterfaceMethodref: case Constants.CONSTANT_Methodref: + case Constants.CONSTANT_Fieldref: + str = (constantToString(((ConstantCP)c).getClassIndex(), + Constants.CONSTANT_Class) + "." + + constantToString(((ConstantCP)c).getNameAndTypeIndex(), + Constants.CONSTANT_NameAndType)); + break; + + default: // Never reached + throw new RuntimeException("Unknown constant type " + tag); + } + + return str; + } + + private static final String escape(String str) { + int len = str.length(); + StringBuffer buf = new StringBuffer(len + 5); + char[] ch = str.toCharArray(); + + for(int i=0; i < len; i++) { + switch(ch[i]) { + case '\n' : buf.append("\\n"); break; + case '\r' : buf.append("\\r"); break; + case '\t' : buf.append("\\t"); break; + case '\b' : buf.append("\\b"); break; + case '"' : buf.append("\\\""); break; + default: buf.append(ch[i]); + } + } + + return buf.toString(); + } + + + /** + * Retrieve constant at `index' from constant pool and resolve it to + * a string representation. + * + * @param index of constant in constant pool + * @param tag expected type + * @return String representation + */ + public String constantToString(int index, byte tag) + throws ClassFormatException + { + Constant c = getConstant(index, tag); + return constantToString(c); + } + + /** + * Dump constant pool to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + public void dump(DataOutputStream file) throws IOException + { + file.writeShort(constant_pool_count); + + for(int i=1; i < constant_pool_count; i++) + if(constant_pool[i] != null) + constant_pool[i].dump(file); + } + + /** + * Get constant from constant pool. + * + * @param index Index in constant pool + * @return Constant value + * @see Constant + */ + public Constant getConstant(int index) { + if (index >= constant_pool.length || index < 0) + throw new ClassFormatException("Invalid constant pool reference: " + + index + ". Constant pool size is: " + + constant_pool.length); + return constant_pool[index]; + } + + /** + * Get constant from constant pool and check whether it has the + * expected type. + * + * @param index Index in constant pool + * @param tag Tag of expected constant, i.e., its type + * @return Constant value + * @see Constant + * @throws ClassFormatException + */ + public Constant getConstant(int index, byte tag) + throws ClassFormatException + { + Constant c; + + c = getConstant(index); + + if(c == null) + throw new ClassFormatException("Constant pool at index " + index + " is null."); + + if(c.getTag() == tag) + return c; + else + throw new ClassFormatException("Expected class `" + Constants.CONSTANT_NAMES[tag] + + "' at index " + index + " and got " + c); + } + + /** + * @return Array of constants. + * @see Constant + */ + public Constant[] getConstantPool() { return constant_pool; } + /** + * Get string from constant pool and bypass the indirection of + * `ConstantClass' and `ConstantString' objects. I.e. these classes have + * an index field that points to another entry of the constant pool of + * type `ConstantUtf8' which contains the real data. + * + * @param index Index in constant pool + * @param tag Tag of expected constant, either ConstantClass or ConstantString + * @return Contents of string reference + * @see ConstantClass + * @see ConstantString + * @throws ClassFormatException + */ + public String getConstantString(int index, byte tag) + throws ClassFormatException + { + Constant c; + int i; + + c = getConstant(index, tag); + + /* This switch() is not that elegant, since the two classes have the + * same contents, they just differ in the name of the index + * field variable. + * But we want to stick to the JVM naming conventions closely though + * we could have solved these more elegantly by using the same + * variable name or by subclassing. + */ + switch(tag) { + case Constants.CONSTANT_Class: i = ((ConstantClass)c).getNameIndex(); break; + case Constants.CONSTANT_String: i = ((ConstantString)c).getStringIndex(); break; + default: + throw new RuntimeException("getConstantString called with illegal tag " + tag); + } + + // Finally get the string from the constant pool + c = getConstant(i, Constants.CONSTANT_Utf8); + return ((ConstantUtf8)c).getBytes(); + } + /** + * @return Length of constant pool. + */ + public int getLength() + { + return constant_pool_count; + } + + /** + * @param constant Constant to set + */ + public void setConstant(int index, Constant constant) { + constant_pool[index] = constant; + } + + /** + * @param constant_pool + */ + public void setConstantPool(Constant[] constant_pool) { + this.constant_pool = constant_pool; + constant_pool_count = (constant_pool == null)? 0 : constant_pool.length; + } + /** + * @return String representation. + */ + public String toString() { + StringBuffer buf = new StringBuffer(); + + for(int i=1; i < constant_pool_count; i++) + buf.append(i + ")" + constant_pool[i] + "\n"); + + return buf.toString(); + } + + /** + * @return deep copy of this constant pool + */ + public ConstantPool copy() { + ConstantPool c = null; + + try { + c = (ConstantPool)clone(); + } catch(CloneNotSupportedException e) {} + + c.constant_pool = new Constant[constant_pool_count]; + + for(int i=1; i < constant_pool_count; i++) { + if(constant_pool[i] != null) + c.constant_pool[i] = constant_pool[i].copy(); + } + + return c; + } +} diff --git a/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantString.java b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantString.java new file mode 100644 index 00000000000..40ea5299f43 --- /dev/null +++ b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantString.java @@ -0,0 +1,150 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +package com.sun.org.apache.bcel.internal.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import com.sun.org.apache.bcel.internal.Constants; +import java.io.*; + +/** + * This class is derived from the abstract + * Constant class + * and represents a reference to a String object. + * + * @author M. Dahm + * @see Constant + */ +public final class ConstantString extends Constant implements ConstantObject { + private int string_index; // Identical to ConstantClass except for this name + + /** + * Initialize from another object. + */ + public ConstantString(ConstantString c) { + this(c.getStringIndex()); + } + /** + * Initialize instance from file data. + * + * @param file Input stream + * @throws IOException + */ + ConstantString(DataInputStream file) throws IOException + { + this((int)file.readUnsignedShort()); + } + /** + * @param string_index Index of Constant_Utf8 in constant pool + */ + public ConstantString(int string_index) + { + super(Constants.CONSTANT_String); + this.string_index = string_index; + } + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + public void accept(Visitor v) { + v.visitConstantString(this); + } + /** + * Dump constant field reference to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + public final void dump(DataOutputStream file) throws IOException + { + file.writeByte(tag); + file.writeShort(string_index); + } + /** + * @return Index in constant pool of the string (ConstantUtf8). + */ + public final int getStringIndex() { return string_index; } + /** + * @param string_index. + */ + public final void setStringIndex(int string_index) { + this.string_index = string_index; + } + /** + * @return String representation. + */ + public final String toString() + { + return super.toString() + "(string_index = " + string_index + ")"; + } + + /** @return String object + */ + public Object getConstantValue(ConstantPool cp) { + Constant c = cp.getConstant(string_index, Constants.CONSTANT_Utf8); + return ((ConstantUtf8)c).getBytes(); + } + + /** @return dereferenced string + */ + public String getBytes(ConstantPool cp) { + return (String)getConstantValue(cp); + } +} diff --git a/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantUtf8.java b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantUtf8.java new file mode 100644 index 00000000000..32e9555e1b1 --- /dev/null +++ b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantUtf8.java @@ -0,0 +1,150 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +package com.sun.org.apache.bcel.internal.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import com.sun.org.apache.bcel.internal.Constants; +import java.io.*; + +/** + * This class is derived from the abstract + * Constant class + * and represents a reference to a Utf8 encoded string. + * + * @author M. Dahm + * @see Constant + */ +public final class ConstantUtf8 extends Constant { + private String bytes; + + /** + * Initialize from another object. + */ + public ConstantUtf8(ConstantUtf8 c) { + this(c.getBytes()); + } + + /** + * Initialize instance from file data. + * + * @param file Input stream + * @throws IOException + */ + ConstantUtf8(DataInputStream file) throws IOException + { + super(Constants.CONSTANT_Utf8); + + bytes = file.readUTF(); + } + + /** + * @param bytes Data + */ + public ConstantUtf8(String bytes) + { + super(Constants.CONSTANT_Utf8); + + if(bytes == null) + throw new IllegalArgumentException("bytes must not be null!"); + + this.bytes = bytes; + } + + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + public void accept(Visitor v) { + v.visitConstantUtf8(this); + } + + /** + * Dump String in Utf8 format to file stream. + * + * @param file Output file stream + * @throws IOException + */ + public final void dump(DataOutputStream file) throws IOException + { + file.writeByte(tag); + file.writeUTF(bytes); + } + + /** + * @return Data converted to string. + */ + public final String getBytes() { return bytes; } + + /** + * @param bytes. + */ + public final void setBytes(String bytes) { + this.bytes = bytes; + } + + /** + * @return String representation + */ + public final String toString() + { + return super.toString() + "(\"" + Utility.replace(bytes, "\n", "\\n") + "\")"; + } +} diff --git a/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantValue.java b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantValue.java new file mode 100644 index 00000000000..e16d47b2fbd --- /dev/null +++ b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/ConstantValue.java @@ -0,0 +1,181 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +package com.sun.org.apache.bcel.internal.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import com.sun.org.apache.bcel.internal.Constants; +import java.io.*; + +/** + * This class is derived from Attribute and represents a constant + * value, i.e., a default value for initializing a class field. + * This class is instantiated by the Attribute.readAttribute() method. + * + * @author M. Dahm + * @see Attribute + */ +public final class ConstantValue extends Attribute { + private int constantvalue_index; + + /** + * Initialize from another object. Note that both objects use the same + * references (shallow copy). Use clone() for a physical copy. + */ + public ConstantValue(ConstantValue c) { + this(c.getNameIndex(), c.getLength(), c.getConstantValueIndex(), + c.getConstantPool()); + } + + /** + * Construct object from file stream. + * @param name_index Name index in constant pool + * @param length Content length in bytes + * @param file Input stream + * @param constant_pool Array of constants + * @throw IOException + */ + ConstantValue(int name_index, int length, DataInputStream file, + ConstantPool constant_pool) throws IOException + { + this(name_index, length, (int)file.readUnsignedShort(), constant_pool); + } + + /** + * @param name_index Name index in constant pool + * @param length Content length in bytes + * @param constantvalue_index Index in constant pool + * @param constant_pool Array of constants + */ + public ConstantValue(int name_index, int length, + int constantvalue_index, + ConstantPool constant_pool) + { + super(Constants.ATTR_CONSTANT_VALUE, name_index, length, constant_pool); + this.constantvalue_index = constantvalue_index; + } + + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + public void accept(Visitor v) { + v.visitConstantValue(this); + } + /** + * Dump constant value attribute to file stream on binary format. + * + * @param file Output file stream + * @throws IOException + */ + public final void dump(DataOutputStream file) throws IOException + { + super.dump(file); + file.writeShort(constantvalue_index); + } + /** + * @return Index in constant pool of constant value. + */ + public final int getConstantValueIndex() { return constantvalue_index; } + + /** + * @param constantvalue_index. + */ + public final void setConstantValueIndex(int constantvalue_index) { + this.constantvalue_index = constantvalue_index; + } + + /** + * @return String representation of constant value. + */ + public final String toString() { + Constant c = constant_pool.getConstant(constantvalue_index); + + String buf; + int i; + + // Print constant to string depending on its type + switch(c.getTag()) { + case Constants.CONSTANT_Long: buf = "" + ((ConstantLong)c).getBytes(); break; + case Constants.CONSTANT_Float: buf = "" + ((ConstantFloat)c).getBytes(); break; + case Constants.CONSTANT_Double: buf = "" + ((ConstantDouble)c).getBytes(); break; + case Constants.CONSTANT_Integer: buf = "" + ((ConstantInteger)c).getBytes(); break; + case Constants.CONSTANT_String: + i = ((ConstantString)c).getStringIndex(); + c = constant_pool.getConstant(i, Constants.CONSTANT_Utf8); + buf = "\"" + Utility.convertString(((ConstantUtf8)c).getBytes()) + "\""; + break; + + default: + throw new IllegalStateException("Type of ConstValue invalid: " + c); + } + + return buf; + } + + /** + * @return deep copy of this attribute + */ + public Attribute copy(ConstantPool constant_pool) { + ConstantValue c = (ConstantValue)clone(); + c.constant_pool = constant_pool; + return c; + } +} diff --git a/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/Deprecated.java b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/Deprecated.java new file mode 100644 index 00000000000..096f77f3b7a --- /dev/null +++ b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/Deprecated.java @@ -0,0 +1,172 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +package com.sun.org.apache.bcel.internal.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import com.sun.org.apache.bcel.internal.Constants; +import java.io.*; + +/** + * This class is derived from Attribute and denotes that this is a + * deprecated method. + * It is instantiated from the Attribute.readAttribute() method. + * + * @author M. Dahm + * @see Attribute + */ +public final class Deprecated extends Attribute { + private byte[] bytes; + + /** + * Initialize from another object. Note that both objects use the same + * references (shallow copy). Use clone() for a physical copy. + */ + public Deprecated(Deprecated c) { + this(c.getNameIndex(), c.getLength(), c.getBytes(), c.getConstantPool()); + } + + /** + * @param name_index Index in constant pool to CONSTANT_Utf8 + * @param length Content length in bytes + * @param bytes Attribute contents + * @param constant_pool Array of constants + */ + public Deprecated(int name_index, int length, byte[] bytes, + ConstantPool constant_pool) + { + super(Constants.ATTR_DEPRECATED, name_index, length, constant_pool); + this.bytes = bytes; + } + + /** + * Construct object from file stream. + * @param name_index Index in constant pool to CONSTANT_Utf8 + * @param length Content length in bytes + * @param file Input stream + * @param constant_pool Array of constants + * @throws IOException + */ + Deprecated(int name_index, int length, DataInputStream file, + ConstantPool constant_pool) throws IOException + { + this(name_index, length, (byte [])null, constant_pool); + + if(length > 0) { + bytes = new byte[length]; + file.readFully(bytes); + System.err.println("Deprecated attribute with length > 0"); + } + } + + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + public void accept(Visitor v) { + v.visitDeprecated(this); + } + + /** + * Dump source file attribute to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + public final void dump(DataOutputStream file) throws IOException + { + super.dump(file); + + if(length > 0) + file.write(bytes, 0, length); + } + + /** + * @return data bytes. + */ + public final byte[] getBytes() { return bytes; } + + /** + * @param bytes. + */ + public final void setBytes(byte[] bytes) { + this.bytes = bytes; + } + + /** + * @return attribute name + */ + public final String toString() { + return Constants.ATTRIBUTE_NAMES[Constants.ATTR_DEPRECATED]; + } + + /** + * @return deep copy of this attribute + */ + public Attribute copy(ConstantPool constant_pool) { + Deprecated c = (Deprecated)clone(); + + if(bytes != null) + c.bytes = (byte[])bytes.clone(); + + c.constant_pool = constant_pool; + return c; + } +} diff --git a/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/DescendingVisitor.java b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/DescendingVisitor.java new file mode 100644 index 00000000000..c25cce0555b --- /dev/null +++ b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/DescendingVisitor.java @@ -0,0 +1,360 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +package com.sun.org.apache.bcel.internal.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +import java.util.Stack; + +/** + * Traverses a JavaClass with another Visitor object 'piggy-backed' + * that is applied to all components of a JavaClass object. I.e. this + * class supplies the traversal strategy, other classes can make use + * of it. + * + * @author M. Dahm + */ +public class DescendingVisitor implements Visitor { + private JavaClass clazz; + private Visitor visitor; + private Stack stack = new Stack(); + + /** @return container of current entitity, i.e., predecessor during traversal + */ + public Object predecessor() { + return predecessor(0); + } + + /** + * @param level nesting level, i.e., 0 returns the direct predecessor + * @return container of current entitity, i.e., predecessor during traversal + */ + public Object predecessor(int level) { + int size = stack.size(); + + if((size < 2) || (level < 0)) + return null; + else + return stack.elementAt(size - (level + 2)); // size - 1 == current + } + + /** @return current object + */ + public Object current() { + return stack.peek(); + } + + /** + * @param clazz Class to traverse + * @param visitor visitor object to apply to all components + */ + public DescendingVisitor(JavaClass clazz, Visitor visitor) { + this.clazz = clazz; + this.visitor = visitor; + } + + /** + * Start traversal. + */ + public void visit() { clazz.accept(this); } + + public void visitJavaClass(JavaClass clazz) { + stack.push(clazz); + clazz.accept(visitor); + + Field[] fields = clazz.getFields(); + for(int i=0; i < fields.length; i++) + fields[i].accept(this); + + Method[] methods = clazz.getMethods(); + for(int i=0; i < methods.length; i++) + methods[i].accept(this); + + Attribute[] attributes = clazz.getAttributes(); + for(int i=0; i < attributes.length; i++) + attributes[i].accept(this); + + clazz.getConstantPool().accept(this); + stack.pop(); + } + + public void visitField(Field field) { + stack.push(field); + field.accept(visitor); + + Attribute[] attributes = field.getAttributes(); + for(int i=0; i < attributes.length; i++) + attributes[i].accept(this); + stack.pop(); + } + + public void visitConstantValue(ConstantValue cv) { + stack.push(cv); + cv.accept(visitor); + stack.pop(); + } + + public void visitMethod(Method method) { + stack.push(method); + method.accept(visitor); + + Attribute[] attributes = method.getAttributes(); + for(int i=0; i < attributes.length; i++) + attributes[i].accept(this); + + stack.pop(); + } + + public void visitExceptionTable(ExceptionTable table) { + stack.push(table); + table.accept(visitor); + stack.pop(); + } + + public void visitCode(Code code) { + stack.push(code); + code.accept(visitor); + + CodeException[] table = code.getExceptionTable(); + for(int i=0; i < table.length; i++) + table[i].accept(this); + + Attribute[] attributes = code.getAttributes(); + for(int i=0; i < attributes.length; i++) + attributes[i].accept(this); + stack.pop(); + } + + public void visitCodeException(CodeException ce) { + stack.push(ce); + ce.accept(visitor); + stack.pop(); + } + + public void visitLineNumberTable(LineNumberTable table) { + stack.push(table); + table.accept(visitor); + + LineNumber[] numbers = table.getLineNumberTable(); + for(int i=0; i < numbers.length; i++) + numbers[i].accept(this); + stack.pop(); + } + + public void visitLineNumber(LineNumber number) { + stack.push(number); + number.accept(visitor); + stack.pop(); + } + + public void visitLocalVariableTable(LocalVariableTable table) { + stack.push(table); + table.accept(visitor); + + LocalVariable[] vars = table.getLocalVariableTable(); + for(int i=0; i < vars.length; i++) + vars[i].accept(this); + stack.pop(); + } + + public void visitStackMap(StackMap table) { + stack.push(table); + table.accept(visitor); + + StackMapEntry[] vars = table.getStackMap(); + + for(int i=0; i < vars.length; i++) + vars[i].accept(this); + stack.pop(); + } + + public void visitStackMapEntry(StackMapEntry var) { + stack.push(var); + var.accept(visitor); + stack.pop(); + } + + public void visitLocalVariable(LocalVariable var) { + stack.push(var); + var.accept(visitor); + stack.pop(); + } + + public void visitConstantPool(ConstantPool cp) { + stack.push(cp); + cp.accept(visitor); + + Constant[] constants = cp.getConstantPool(); + for(int i=1; i < constants.length; i++) { + if(constants[i] != null) + constants[i].accept(this); + } + + stack.pop(); + } + + public void visitConstantClass(ConstantClass constant) { + stack.push(constant); + constant.accept(visitor); + stack.pop(); + } + + public void visitConstantDouble(ConstantDouble constant) { + stack.push(constant); + constant.accept(visitor); + stack.pop(); + } + + public void visitConstantFieldref(ConstantFieldref constant) { + stack.push(constant); + constant.accept(visitor); + stack.pop(); + } + + public void visitConstantFloat(ConstantFloat constant) { + stack.push(constant); + constant.accept(visitor); + stack.pop(); + } + + public void visitConstantInteger(ConstantInteger constant) { + stack.push(constant); + constant.accept(visitor); + stack.pop(); + } + + public void visitConstantInterfaceMethodref(ConstantInterfaceMethodref constant) { + stack.push(constant); + constant.accept(visitor); + stack.pop(); + } + + public void visitConstantLong(ConstantLong constant) { + stack.push(constant); + constant.accept(visitor); + stack.pop(); + } + + public void visitConstantMethodref(ConstantMethodref constant) { + stack.push(constant); + constant.accept(visitor); + stack.pop(); + } + + public void visitConstantNameAndType(ConstantNameAndType constant) { + stack.push(constant); + constant.accept(visitor); + stack.pop(); + } + + public void visitConstantString(ConstantString constant) { + stack.push(constant); + constant.accept(visitor); + stack.pop(); + } + + public void visitConstantUtf8(ConstantUtf8 constant) { + stack.push(constant); + constant.accept(visitor); + stack.pop(); + } + + public void visitInnerClasses(InnerClasses ic) { + stack.push(ic); + ic.accept(visitor); + + InnerClass[] ics = ic.getInnerClasses(); + for(int i=0; i < ics.length; i++) + ics[i].accept(this); + stack.pop(); + } + + public void visitInnerClass(InnerClass inner) { + stack.push(inner); + inner.accept(visitor); + stack.pop(); + } + + public void visitDeprecated(Deprecated attribute) { + stack.push(attribute); + attribute.accept(visitor); + stack.pop(); + } + + public void visitSignature(Signature attribute) { + stack.push(attribute); + attribute.accept(visitor); + stack.pop(); + } + + public void visitSourceFile(SourceFile attribute) { + stack.push(attribute); + attribute.accept(visitor); + stack.pop(); + } + + public void visitSynthetic(Synthetic attribute) { + stack.push(attribute); + attribute.accept(visitor); + stack.pop(); + } + + public void visitUnknown(Unknown attribute) { + stack.push(attribute); + attribute.accept(visitor); + stack.pop(); + } +} diff --git a/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/EmptyVisitor.java b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/EmptyVisitor.java new file mode 100644 index 00000000000..88fe11e6a8a --- /dev/null +++ b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/EmptyVisitor.java @@ -0,0 +1,108 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +package com.sun.org.apache.bcel.internal.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import com.sun.org.apache.bcel.internal.classfile.*; +import com.sun.org.apache.bcel.internal.*; + +/** + * Visitor with empty method bodies, can be extended and used in conjunction with the + * DescendingVisitor class, e.g. + * + * By courtesy of David Spencer. + * + * @see DescendingVisitor + * + */ +public class EmptyVisitor implements Visitor { + protected EmptyVisitor() { } + + public void visitCode(Code obj) {} + public void visitCodeException(CodeException obj) {} + public void visitConstantClass(ConstantClass obj) {} + public void visitConstantDouble(ConstantDouble obj) {} + public void visitConstantFieldref(ConstantFieldref obj) {} + public void visitConstantFloat(ConstantFloat obj) {} + public void visitConstantInteger(ConstantInteger obj) {} + public void visitConstantInterfaceMethodref(ConstantInterfaceMethodref obj) {} + public void visitConstantLong(ConstantLong obj) {} + public void visitConstantMethodref(ConstantMethodref obj) {} + public void visitConstantNameAndType(ConstantNameAndType obj) {} + public void visitConstantPool(ConstantPool obj) {} + public void visitConstantString(ConstantString obj) {} + public void visitConstantUtf8(ConstantUtf8 obj) {} + public void visitConstantValue(ConstantValue obj) {} + public void visitDeprecated(Deprecated obj) {} + public void visitExceptionTable(ExceptionTable obj) {} + public void visitField(Field obj) {} + public void visitInnerClass(InnerClass obj) {} + public void visitInnerClasses(InnerClasses obj) {} + public void visitJavaClass(JavaClass obj) {} + public void visitLineNumber(LineNumber obj) {} + public void visitLineNumberTable(LineNumberTable obj) {} + public void visitLocalVariable(LocalVariable obj) {} + public void visitLocalVariableTable(LocalVariableTable obj) {} + public void visitMethod(Method obj) {} + public void visitSignature(Signature obj) {} + public void visitSourceFile(SourceFile obj) {} + public void visitSynthetic(Synthetic obj) {} + public void visitUnknown(Unknown obj) {} + public void visitStackMap(StackMap obj) {} + public void visitStackMapEntry(StackMapEntry obj) {} +} diff --git a/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/ExceptionTable.java b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/ExceptionTable.java new file mode 100644 index 00000000000..0a9e1dcf155 --- /dev/null +++ b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/ExceptionTable.java @@ -0,0 +1,205 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +package com.sun.org.apache.bcel.internal.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import com.sun.org.apache.bcel.internal.Constants; +import java.io.*; + +/** + * This class represents the table of exceptions that are thrown by a + * method. This attribute may be used once per method. The name of + * this class is ExceptionTable for historical reasons; The + * Java Virtual Machine Specification, Second Edition defines this + * attribute using the name Exceptions (which is inconsistent + * with the other classes). + * + * @author M. Dahm + * @see Code + */ +public final class ExceptionTable extends Attribute { + private int number_of_exceptions; // Table of indices into + private int[] exception_index_table; // constant pool + + /** + * Initialize from another object. Note that both objects use the same + * references (shallow copy). Use copy() for a physical copy. + */ + public ExceptionTable(ExceptionTable c) { + this(c.getNameIndex(), c.getLength(), c.getExceptionIndexTable(), + c.getConstantPool()); + } + + /** + * @param name_index Index in constant pool + * @param length Content length in bytes + * @param exception_index_table Table of indices in constant pool + * @param constant_pool Array of constants + */ + public ExceptionTable(int name_index, int length, + int[] exception_index_table, + ConstantPool constant_pool) + { + super(Constants.ATTR_EXCEPTIONS, name_index, length, constant_pool); + setExceptionIndexTable(exception_index_table); + } + + /** + * Construct object from file stream. + * @param name_index Index in constant pool + * @param length Content length in bytes + * @param file Input stream + * @param constant_pool Array of constants + * @throws IOException + */ + ExceptionTable(int name_index, int length, DataInputStream file, + ConstantPool constant_pool) throws IOException + { + this(name_index, length, (int[])null, constant_pool); + + number_of_exceptions = file.readUnsignedShort(); + exception_index_table = new int[number_of_exceptions]; + + for(int i=0; i < number_of_exceptions; i++) + exception_index_table[i] = file.readUnsignedShort(); + } + + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + public void accept(Visitor v) { + v.visitExceptionTable(this); + } + + /** + * Dump exceptions attribute to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + public final void dump(DataOutputStream file) throws IOException + { + super.dump(file); + file.writeShort(number_of_exceptions); + for(int i=0; i < number_of_exceptions; i++) + file.writeShort(exception_index_table[i]); + } + + /** + * @return Array of indices into constant pool of thrown exceptions. + */ + public final int[] getExceptionIndexTable() {return exception_index_table;} + /** + * @return Length of exception table. + */ + public final int getNumberOfExceptions() { return number_of_exceptions; } + + /** + * @return class names of thrown exceptions + */ + public final String[] getExceptionNames() { + String[] names = new String[number_of_exceptions]; + for(int i=0; i < number_of_exceptions; i++) + names[i] = constant_pool.getConstantString(exception_index_table[i], + Constants.CONSTANT_Class). + replace('/', '.'); + return names; + } + + /** + * @param exception_index_table. + * Also redefines number_of_exceptions according to table length. + */ + public final void setExceptionIndexTable(int[] exception_index_table) { + this.exception_index_table = exception_index_table; + number_of_exceptions = (exception_index_table == null)? 0 : + exception_index_table.length; + } + /** + * @return String representation, i.e., a list of thrown exceptions. + */ + public final String toString() { + StringBuffer buf = new StringBuffer(""); + String str; + + for(int i=0; i < number_of_exceptions; i++) { + str = constant_pool.getConstantString(exception_index_table[i], + Constants.CONSTANT_Class); + buf.append(Utility.compactClassName(str, false)); + + if(i < number_of_exceptions - 1) + buf.append(", "); + } + + return buf.toString(); + } + + /** + * @return deep copy of this attribute + */ + public Attribute copy(ConstantPool constant_pool) { + ExceptionTable c = (ExceptionTable)clone(); + c.exception_index_table = (int[])exception_index_table.clone(); + c.constant_pool = constant_pool; + return c; + } +} diff --git a/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/Field.java b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/Field.java new file mode 100644 index 00000000000..6bc42ee48be --- /dev/null +++ b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/Field.java @@ -0,0 +1,168 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +package com.sun.org.apache.bcel.internal.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +import com.sun.org.apache.bcel.internal.Constants; +import com.sun.org.apache.bcel.internal.generic.Type; +import java.io.*; + +/** + * This class represents the field info structure, i.e., the representation + * for a variable in the class. See JVM specification for details. + * + * @author M. Dahm + */ +public final class Field extends FieldOrMethod { + /** + * Initialize from another object. Note that both objects use the same + * references (shallow copy). Use clone() for a physical copy. + */ + public Field(Field c) { + super(c); + } + + /** + * Construct object from file stream. + * @param file Input stream + */ + Field(DataInputStream file, ConstantPool constant_pool) + throws IOException, ClassFormatException + { + super(file, constant_pool); + } + + /** + * @param access_flags Access rights of field + * @param name_index Points to field name in constant pool + * @param signature_index Points to encoded signature + * @param attributes Collection of attributes + * @param constant_pool Array of constants + */ + public Field(int access_flags, int name_index, int signature_index, + Attribute[] attributes, ConstantPool constant_pool) + { + super(access_flags, name_index, signature_index, attributes, constant_pool); + } + + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + public void accept(Visitor v) { + v.visitField(this); + } + + /** + * @return constant value associated with this field (may be null) + */ + public final ConstantValue getConstantValue() { + for(int i=0; i < attributes_count; i++) + if(attributes[i].getTag() == Constants.ATTR_CONSTANT_VALUE) + return (ConstantValue)attributes[i]; + + return null; + } + + /** + * Return string representation close to declaration format, + * `public static final short MAX = 100', e.g.. + * + * @return String representation of field, including the signature. + */ + public final String toString() { + String name, signature, access; // Short cuts to constant pool + + // Get names from constant pool + access = Utility.accessToString(access_flags); + access = access.equals("")? "" : (access + " "); + signature = Utility.signatureToString(getSignature()); + name = getName(); + + StringBuffer buf = new StringBuffer(access + signature + " " + name); + ConstantValue cv = getConstantValue(); + + if(cv != null) + buf.append(" = " + cv); + + for(int i=0; i < attributes_count; i++) { + Attribute a = attributes[i]; + + if(!(a instanceof ConstantValue)) + buf.append(" [" + a.toString() + "]"); + } + + return buf.toString(); + } + + /** + * @return deep copy of this field + */ + public final Field copy(ConstantPool constant_pool) { + return (Field)copy_(constant_pool); + } + + /** + * @return type of field + */ + public Type getType() { + return Type.getReturnType(getSignature()); + } +} diff --git a/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/FieldOrMethod.java b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/FieldOrMethod.java new file mode 100644 index 00000000000..86b7da20be7 --- /dev/null +++ b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/FieldOrMethod.java @@ -0,0 +1,226 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +package com.sun.org.apache.bcel.internal.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +import com.sun.org.apache.bcel.internal.Constants; +import java.io.*; + +/** + * Abstract super class for fields and methods. + * + * @author M. Dahm + */ +public abstract class FieldOrMethod extends AccessFlags implements Cloneable, Node { + protected int name_index; // Points to field name in constant pool + protected int signature_index; // Points to encoded signature + protected int attributes_count;// No. of attributes + protected Attribute[] attributes; // Collection of attributes + protected ConstantPool constant_pool; + + FieldOrMethod() {} + + /** + * Initialize from another object. Note that both objects use the same + * references (shallow copy). Use clone() for a physical copy. + */ + protected FieldOrMethod(FieldOrMethod c) { + this(c.getAccessFlags(), c.getNameIndex(), c.getSignatureIndex(), + c.getAttributes(), c.getConstantPool()); + } + + /** + * Construct object from file stream. + * @param file Input stream + * @throws IOException + * @throws ClassFormatException + */ + protected FieldOrMethod(DataInputStream file, ConstantPool constant_pool) + throws IOException, ClassFormatException + { + this(file.readUnsignedShort(), file.readUnsignedShort(), + file.readUnsignedShort(), null, constant_pool); + + attributes_count = file.readUnsignedShort(); + attributes = new Attribute[attributes_count]; + for(int i=0; i < attributes_count; i++) + attributes[i] = Attribute.readAttribute(file, constant_pool); + } + + /** + * @param access_flags Access rights of method + * @param name_index Points to field name in constant pool + * @param signature_index Points to encoded signature + * @param attributes Collection of attributes + * @param constant_pool Array of constants + */ + protected FieldOrMethod(int access_flags, int name_index, int signature_index, + Attribute[] attributes, ConstantPool constant_pool) + { + this.access_flags = access_flags; + this.name_index = name_index; + this.signature_index = signature_index; + this.constant_pool = constant_pool; + + setAttributes(attributes); + } + + /** + * Dump object to file stream on binary format. + * + * @param file Output file stream + * @throws IOException + */ + public final void dump(DataOutputStream file) throws IOException + { + file.writeShort(access_flags); + file.writeShort(name_index); + file.writeShort(signature_index); + file.writeShort(attributes_count); + + for(int i=0; i < attributes_count; i++) + attributes[i].dump(file); + } + + /** + * @return Collection of object attributes. + */ + public final Attribute[] getAttributes() { return attributes; } + + /** + * @param attributes Collection of object attributes. + */ + public final void setAttributes(Attribute[] attributes) { + this.attributes = attributes; + attributes_count = (attributes == null)? 0 : attributes.length; + } + + /** + * @return Constant pool used by this object. + */ + public final ConstantPool getConstantPool() { return constant_pool; } + + /** + * @param constant_pool Constant pool to be used for this object. + */ + public final void setConstantPool(ConstantPool constant_pool) { + this.constant_pool = constant_pool; + } + + /** + * @return Index in constant pool of object's name. + */ + public final int getNameIndex() { return name_index; } + + /** + * @param name_index Index in constant pool of object's name. + */ + public final void setNameIndex(int name_index) { + this.name_index = name_index; + } + + /** + * @return Index in constant pool of field signature. + */ + public final int getSignatureIndex() { return signature_index; } + + /** + * @param signature_index Index in constant pool of field signature. + */ + public final void setSignatureIndex(int signature_index) { + this.signature_index = signature_index; + } + + /** + * @return Name of object, i.e., method name or field name + */ + public final String getName() { + ConstantUtf8 c; + c = (ConstantUtf8)constant_pool.getConstant(name_index, + Constants.CONSTANT_Utf8); + return c.getBytes(); + } + + /** + * @return String representation of object's type signature (java style) + */ + public final String getSignature() { + ConstantUtf8 c; + c = (ConstantUtf8)constant_pool.getConstant(signature_index, + Constants.CONSTANT_Utf8); + return c.getBytes(); + } + + /** + * @return deep copy of this field + */ + protected FieldOrMethod copy_(ConstantPool constant_pool) { + FieldOrMethod c = null; + + try { + c = (FieldOrMethod)clone(); + } catch(CloneNotSupportedException e) {} + + c.constant_pool = constant_pool; + c.attributes = new Attribute[attributes_count]; + + for(int i=0; i < attributes_count; i++) + c.attributes[i] = attributes[i].copy(constant_pool); + + return c; + } +} diff --git a/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/InnerClass.java b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/InnerClass.java new file mode 100644 index 00000000000..8693fa6a1f0 --- /dev/null +++ b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/InnerClass.java @@ -0,0 +1,224 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +package com.sun.org.apache.bcel.internal.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import com.sun.org.apache.bcel.internal.Constants; +import java.io.*; + +/** + * This class represents a inner class attribute, i.e., the class + * indices of the inner and outer classes, the name and the attributes + * of the inner class. + * + * @author M. Dahm + * @see InnerClasses + */ +public final class InnerClass implements Cloneable, Node { + private int inner_class_index; + private int outer_class_index; + private int inner_name_index; + private int inner_access_flags; + + /** + * Initialize from another object. + */ + public InnerClass(InnerClass c) { + this(c.getInnerClassIndex(), c.getOuterClassIndex(), c.getInnerNameIndex(), + c.getInnerAccessFlags()); + } + + /** + * Construct object from file stream. + * @param file Input stream + * @throws IOException + */ + InnerClass(DataInputStream file) throws IOException + { + this(file.readUnsignedShort(), file.readUnsignedShort(), + file.readUnsignedShort(), file.readUnsignedShort()); + } + + /** + * @param inner_class_index Class index in constant pool of inner class + * @param outer_class_index Class index in constant pool of outer class + * @param inner_name_index Name index in constant pool of inner class + * @param inner_access_flags Access flags of inner class + */ + public InnerClass(int inner_class_index, int outer_class_index, + int inner_name_index, int inner_access_flags) + { + this.inner_class_index = inner_class_index; + this.outer_class_index = outer_class_index; + this.inner_name_index = inner_name_index; + this.inner_access_flags = inner_access_flags; + } + + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + public void accept(Visitor v) { + v.visitInnerClass(this); + } + /** + * Dump inner class attribute to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + public final void dump(DataOutputStream file) throws IOException + { + file.writeShort(inner_class_index); + file.writeShort(outer_class_index); + file.writeShort(inner_name_index); + file.writeShort(inner_access_flags); + } + /** + * @return access flags of inner class. + */ + public final int getInnerAccessFlags() { return inner_access_flags; } + /** + * @return class index of inner class. + */ + public final int getInnerClassIndex() { return inner_class_index; } + /** + * @return name index of inner class. + */ + public final int getInnerNameIndex() { return inner_name_index; } + /** + * @return class index of outer class. + */ + public final int getOuterClassIndex() { return outer_class_index; } + /** + * @param inner_access_flags. + */ + public final void setInnerAccessFlags(int inner_access_flags) { + this.inner_access_flags = inner_access_flags; + } + /** + * @param inner_class_index. + */ + public final void setInnerClassIndex(int inner_class_index) { + this.inner_class_index = inner_class_index; + } + /** + * @param inner_name_index. + */ + public final void setInnerNameIndex(int inner_name_index) { + this.inner_name_index = inner_name_index; + } + /** + * @param outer_class_index. + */ + public final void setOuterClassIndex(int outer_class_index) { + this.outer_class_index = outer_class_index; + } + /** + * @return String representation. + */ + public final String toString() { + return "InnerClass(" + inner_class_index + ", " + outer_class_index + + ", " + inner_name_index + ", " + inner_access_flags + ")"; + } + + /** + * @return Resolved string representation + */ + public final String toString(ConstantPool constant_pool) { + String inner_class_name, outer_class_name, inner_name, access; + + inner_class_name = constant_pool.getConstantString(inner_class_index, + Constants.CONSTANT_Class); + inner_class_name = Utility.compactClassName(inner_class_name); + + if (outer_class_index != 0) { + outer_class_name = constant_pool.getConstantString(outer_class_index, + Constants.CONSTANT_Class); + outer_class_name = Utility.compactClassName(outer_class_name); + } + else + outer_class_name = ""; + + if(inner_name_index != 0) + inner_name = ((ConstantUtf8)constant_pool. + getConstant(inner_name_index, Constants.CONSTANT_Utf8)).getBytes(); + else + inner_name = ""; + + access = Utility.accessToString(inner_access_flags, true); + access = access.equals("")? "" : (access + " "); + + return "InnerClass:" + access + inner_class_name + + "(\"" + outer_class_name + "\", \"" + inner_name + "\")"; + } + + /** + * @return deep copy of this object + */ + public InnerClass copy() { + try { + return (InnerClass)clone(); + } catch(CloneNotSupportedException e) {} + + return null; + } +} diff --git a/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/InnerClasses.java b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/InnerClasses.java new file mode 100644 index 00000000000..da320361327 --- /dev/null +++ b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/InnerClasses.java @@ -0,0 +1,184 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +package com.sun.org.apache.bcel.internal.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import com.sun.org.apache.bcel.internal.Constants; +import java.io.*; + +/** + * This class is derived from Attribute and denotes that this class + * is an Inner class of another. + * to the source file of this class. + * It is instantiated from the Attribute.readAttribute() method. + * + * @author M. Dahm + * @see Attribute + */ +public final class InnerClasses extends Attribute { + private InnerClass[] inner_classes; + private int number_of_classes; + + /** + * Initialize from another object. Note that both objects use the same + * references (shallow copy). Use clone() for a physical copy. + */ + public InnerClasses(InnerClasses c) { + this(c.getNameIndex(), c.getLength(), c.getInnerClasses(), + c.getConstantPool()); + } + + /** + * @param name_index Index in constant pool to CONSTANT_Utf8 + * @param length Content length in bytes + * @param inner_classes array of inner classes attributes + * @param constant_pool Array of constants + * @param sourcefile_index Index in constant pool to CONSTANT_Utf8 + */ + public InnerClasses(int name_index, int length, + InnerClass[] inner_classes, + ConstantPool constant_pool) + { + super(Constants.ATTR_INNER_CLASSES, name_index, length, constant_pool); + setInnerClasses(inner_classes); + } + + /** + * Construct object from file stream. + * + * @param name_index Index in constant pool to CONSTANT_Utf8 + * @param length Content length in bytes + * @param file Input stream + * @param constant_pool Array of constants + * @throws IOException + */ + InnerClasses(int name_index, int length, DataInputStream file, + ConstantPool constant_pool) throws IOException + { + this(name_index, length, (InnerClass[])null, constant_pool); + + number_of_classes = file.readUnsignedShort(); + inner_classes = new InnerClass[number_of_classes]; + + for(int i=0; i < number_of_classes; i++) + inner_classes[i] = new InnerClass(file); + } + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + public void accept(Visitor v) { + v.visitInnerClasses(this); + } + /** + * Dump source file attribute to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + public final void dump(DataOutputStream file) throws IOException + { + super.dump(file); + file.writeShort(number_of_classes); + + for(int i=0; i < number_of_classes; i++) + inner_classes[i].dump(file); + } + + /** + * @return array of inner class "records" + */ + public final InnerClass[] getInnerClasses() { return inner_classes; } + + /** + * @param inner_classes. + */ + public final void setInnerClasses(InnerClass[] inner_classes) { + this.inner_classes = inner_classes; + number_of_classes = (inner_classes == null)? 0 : inner_classes.length; + } + + /** + * @return String representation. + */ + public final String toString() { + StringBuffer buf = new StringBuffer(); + + for(int i=0; i < number_of_classes; i++) + buf.append(inner_classes[i].toString(constant_pool) + "\n"); + + return buf.toString(); + } + + /** + * @return deep copy of this attribute + */ + public Attribute copy(ConstantPool constant_pool) { + InnerClasses c = (InnerClasses)clone(); + + c.inner_classes = new InnerClass[number_of_classes]; + for(int i=0; i < number_of_classes; i++) + c.inner_classes[i] = inner_classes[i].copy(); + + c.constant_pool = constant_pool; + return c; + } +} diff --git a/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/JavaClass.java b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/JavaClass.java new file mode 100644 index 00000000000..1c0d54ebb75 --- /dev/null +++ b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/JavaClass.java @@ -0,0 +1,824 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +package com.sun.org.apache.bcel.internal.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import com.sun.org.apache.bcel.internal.Constants; +import com.sun.org.apache.bcel.internal.util.SyntheticRepository; +import com.sun.org.apache.bcel.internal.util.ClassVector; +import com.sun.org.apache.bcel.internal.util.ClassQueue; +import com.sun.org.apache.bcel.internal.generic.Type; + +import java.io.*; +import java.util.StringTokenizer; + +/** + * Represents a Java class, i.e., the data structures, constant pool, + * fields, methods and commands contained in a Java .class file. + * See JVM + * specification for details. + + * The intent of this class is to represent a parsed or otherwise existing + * class file. Those interested in programatically generating classes + * should see the ClassGen class. + + * @see com.sun.org.apache.bcel.internal.generic.ClassGen + * @author M. Dahm + */ +public class JavaClass extends AccessFlags implements Cloneable, Node { + private String file_name; + private String package_name; + private String source_file_name = ""; + private int class_name_index; + private int superclass_name_index; + private String class_name; + private String superclass_name; + private int major, minor; // Compiler version + private ConstantPool constant_pool; // Constant pool + private int[] interfaces; // implemented interfaces + private String[] interface_names; + private Field[] fields; // Fields, i.e., variables of class + private Method[] methods; // methods defined in the class + private Attribute[] attributes; // attributes defined in the class + private byte source = HEAP; // Generated in memory + + public static final byte HEAP = 1; + public static final byte FILE = 2; + public static final byte ZIP = 3; + + static boolean debug = false; // Debugging on/off + static char sep = '/'; // directory separator + + /** + * In cases where we go ahead and create something, + * use the default SyntheticRepository, because we + * don't know any better. + */ + private transient com.sun.org.apache.bcel.internal.util.Repository repository = + SyntheticRepository.getInstance(); + + /** + * Constructor gets all contents as arguments. + * + * @param class_name_index Index into constant pool referencing a + * ConstantClass that represents this class. + * @param superclass_name_index Index into constant pool referencing a + * ConstantClass that represents this class's superclass. + * @param file_name File name + * @param major Major compiler version + * @param minor Minor compiler version + * @param access_flags Access rights defined by bit flags + * @param constant_pool Array of constants + * @param interfaces Implemented interfaces + * @param fields Class fields + * @param methods Class methods + * @param attributes Class attributes + * @param source Read from file or generated in memory? + */ + public JavaClass(int class_name_index, + int superclass_name_index, + String file_name, + int major, + int minor, + int access_flags, + ConstantPool constant_pool, + int[] interfaces, + Field[] fields, + Method[] methods, + Attribute[] attributes, + byte source) + { + if(interfaces == null) // Allowed for backward compatibility + interfaces = new int[0]; + if(attributes == null) + this.attributes = new Attribute[0]; + if(fields == null) + fields = new Field[0]; + if(methods == null) + methods = new Method[0]; + + this.class_name_index = class_name_index; + this.superclass_name_index = superclass_name_index; + this.file_name = file_name; + this.major = major; + this.minor = minor; + this.access_flags = access_flags; + this.constant_pool = constant_pool; + this.interfaces = interfaces; + this.fields = fields; + this.methods = methods; + this.attributes = attributes; + this.source = source; + + // Get source file name if available + for(int i=0; i < attributes.length; i++) { + if(attributes[i] instanceof SourceFile) { + source_file_name = ((SourceFile)attributes[i]).getSourceFileName(); + break; + } + } + + /* According to the specification the following entries must be of type + * `ConstantClass' but we check that anyway via the + * `ConstPool.getConstant' method. + */ + class_name = constant_pool.getConstantString(class_name_index, + Constants.CONSTANT_Class); + class_name = Utility.compactClassName(class_name, false); + + int index = class_name.lastIndexOf('.'); + if(index < 0) + package_name = ""; + else + package_name = class_name.substring(0, index); + + if(superclass_name_index > 0) { // May be zero -> class is java.lang.Object + superclass_name = constant_pool.getConstantString(superclass_name_index, + Constants.CONSTANT_Class); + superclass_name = Utility.compactClassName(superclass_name, false); + } + else + superclass_name = "java.lang.Object"; + + interface_names = new String[interfaces.length]; + for(int i=0; i < interfaces.length; i++) { + String str = constant_pool.getConstantString(interfaces[i], Constants.CONSTANT_Class); + interface_names[i] = Utility.compactClassName(str, false); + } + } + + /** + * Constructor gets all contents as arguments. + * + * @param class_name_index Class name + * @param superclass_name_index Superclass name + * @param file_name File name + * @param major Major compiler version + * @param minor Minor compiler version + * @param access_flags Access rights defined by bit flags + * @param constant_pool Array of constants + * @param interfaces Implemented interfaces + * @param fields Class fields + * @param methods Class methods + * @param attributes Class attributes + */ + public JavaClass(int class_name_index, + int superclass_name_index, + String file_name, + int major, + int minor, + int access_flags, + ConstantPool constant_pool, + int[] interfaces, + Field[] fields, + Method[] methods, + Attribute[] attributes) { + this(class_name_index, superclass_name_index, file_name, major, minor, access_flags, + constant_pool, interfaces, fields, methods, attributes, HEAP); + } + + + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + public void accept(Visitor v) { + v.visitJavaClass(this); + } + + /* Print debug information depending on `JavaClass.debug' + */ + static final void Debug(String str) { + if(debug) + System.out.println(str); + } + + /** + * Dump class to a file. + * + * @param file Output file + * @throws IOException + */ + public void dump(File file) throws IOException + { + String parent = file.getParent(); + + if(parent != null) { + File dir = new File(parent); + + if(dir != null) + dir.mkdirs(); + } + + dump(new DataOutputStream(new FileOutputStream(file))); + } + + /** + * Dump class to a file named file_name. + * + * @param file_name Output file name + * @exception IOException + */ + public void dump(String file_name) throws IOException + { + dump(new File(file_name)); + } + + /** + * @return class in binary format + */ + public byte[] getBytes() { + ByteArrayOutputStream s = new ByteArrayOutputStream(); + DataOutputStream ds = new DataOutputStream(s); + + try { + dump(ds); + } catch(IOException e) { + e.printStackTrace(); + } finally { + try { ds.close(); } catch(IOException e2) { e2.printStackTrace(); } + } + + return s.toByteArray(); + } + + /** + * Dump Java class to output stream in binary format. + * + * @param file Output stream + * @exception IOException + */ + public void dump(OutputStream file) throws IOException { + dump(new DataOutputStream(file)); + } + + /** + * Dump Java class to output stream in binary format. + * + * @param file Output stream + * @exception IOException + */ + public void dump(DataOutputStream file) throws IOException + { + file.writeInt(0xcafebabe); + file.writeShort(minor); + file.writeShort(major); + + constant_pool.dump(file); + + file.writeShort(access_flags); + file.writeShort(class_name_index); + file.writeShort(superclass_name_index); + + file.writeShort(interfaces.length); + for(int i=0; i < interfaces.length; i++) + file.writeShort(interfaces[i]); + + file.writeShort(fields.length); + for(int i=0; i < fields.length; i++) + fields[i].dump(file); + + file.writeShort(methods.length); + for(int i=0; i < methods.length; i++) + methods[i].dump(file); + + if(attributes != null) { + file.writeShort(attributes.length); + for(int i=0; i < attributes.length; i++) + attributes[i].dump(file); + } + else + file.writeShort(0); + + file.close(); + } + + /** + * @return Attributes of the class. + */ + public Attribute[] getAttributes() { return attributes; } + + /** + * @return Class name. + */ + public String getClassName() { return class_name; } + + /** + * @return Package name. + */ + public String getPackageName() { return package_name; } + + /** + * @return Class name index. + */ + public int getClassNameIndex() { return class_name_index; } + + /** + * @return Constant pool. + */ + public ConstantPool getConstantPool() { return constant_pool; } + + /** + * @return Fields, i.e., variables of the class. Like the JVM spec + * mandates for the classfile format, these fields are those specific to + * this class, and not those of the superclass or superinterfaces. + */ + public Field[] getFields() { return fields; } + + /** + * @return File name of class, aka SourceFile attribute value + */ + public String getFileName() { return file_name; } + + /** + * @return Names of implemented interfaces. + */ + public String[] getInterfaceNames() { return interface_names; } + + /** + * @return Indices in constant pool of implemented interfaces. + */ + public int[] getInterfaceIndices() { return interfaces; } + + /** + * @return Major number of class file version. + */ + public int getMajor() { return major; } + + /** + * @return Methods of the class. + */ + public Method[] getMethods() { return methods; } + + /** + * @return A com.sun.org.apache.bcel.internal.classfile.Method corresponding to + * java.lang.reflect.Method if any + */ + public Method getMethod(java.lang.reflect.Method m) { + for(int i = 0; i < methods.length; i++) { + Method method = methods[i]; + + if(m.getName().equals(method.getName()) && + (m.getModifiers() == method.getModifiers()) && + Type.getSignature(m).equals(method.getSignature())) { + return method; + } + } + + return null; + } + + /** + * @return Minor number of class file version. + */ + public int getMinor() { return minor; } + + /** + * @return sbsolute path to file where this class was read from + */ + public String getSourceFileName() { return source_file_name; } + + /** + * @return Superclass name. + */ + public String getSuperclassName() { return superclass_name; } + + /** + * @return Class name index. + */ + public int getSuperclassNameIndex() { return superclass_name_index; } + + static { + // Debugging ... on/off + String debug = null, sep = null; + + try { + debug = System.getProperty("JavaClass.debug"); + // Get path separator either / or \ usually + sep = System.getProperty("file.separator"); + } + catch (SecurityException e) { + // falls through + } + + if(debug != null) + JavaClass.debug = new Boolean(debug).booleanValue(); + + if(sep != null) + try { + JavaClass.sep = sep.charAt(0); + } catch(StringIndexOutOfBoundsException e) {} // Never reached + } + + /** + * @param attributes . + */ + public void setAttributes(Attribute[] attributes) { + this.attributes = attributes; + } + + /** + * @param class_name . + */ + public void setClassName(String class_name) { + this.class_name = class_name; + } + + /** + * @param class_name_index . + */ + public void setClassNameIndex(int class_name_index) { + this.class_name_index = class_name_index; + } + + /** + * @param constant_pool . + */ + public void setConstantPool(ConstantPool constant_pool) { + this.constant_pool = constant_pool; + } + + /** + * @param fields . + */ + public void setFields(Field[] fields) { + this.fields = fields; + } + + /** + * Set File name of class, aka SourceFile attribute value + */ + public void setFileName(String file_name) { + this.file_name = file_name; + } + + /** + * @param interface_names . + */ + public void setInterfaceNames(String[] interface_names) { + this.interface_names = interface_names; + } + + /** + * @param interfaces . + */ + public void setInterfaces(int[] interfaces) { + this.interfaces = interfaces; + } + + /** + * @param major . + */ + public void setMajor(int major) { + this.major = major; + } + + /** + * @param methods . + */ + public void setMethods(Method[] methods) { + this.methods = methods; + } + + /** + * @param minor . + */ + public void setMinor(int minor) { + this.minor = minor; + } + + /** + * Set absolute path to file this class was read from. + */ + public void setSourceFileName(String source_file_name) { + this.source_file_name = source_file_name; + } + + /** + * @param superclass_name . + */ + public void setSuperclassName(String superclass_name) { + this.superclass_name = superclass_name; + } + + /** + * @param superclass_name_index . + */ + public void setSuperclassNameIndex(int superclass_name_index) { + this.superclass_name_index = superclass_name_index; + } + + /** + * @return String representing class contents. + */ + public String toString() { + String access = Utility.accessToString(access_flags, true); + access = access.equals("")? "" : (access + " "); + + StringBuffer buf = new StringBuffer(access + + Utility.classOrInterface(access_flags) + + " " + + class_name + " extends " + + Utility.compactClassName(superclass_name, + false) + '\n'); + int size = interfaces.length; + + if(size > 0) { + buf.append("implements\t\t"); + + for(int i=0; i < size; i++) { + buf.append(interface_names[i]); + if(i < size - 1) + buf.append(", "); + } + + buf.append('\n'); + } + + buf.append("filename\t\t" + file_name + '\n'); + buf.append("compiled from\t\t" + source_file_name + '\n'); + buf.append("compiler version\t" + major + "." + minor + '\n'); + buf.append("access flags\t\t" + access_flags + '\n'); + buf.append("constant pool\t\t" + constant_pool.getLength() + " entries\n"); + buf.append("ACC_SUPER flag\t\t" + isSuper() + "\n"); + + if(attributes.length > 0) { + buf.append("\nAttribute(s):\n"); + for(int i=0; i < attributes.length; i++) + buf.append(indent(attributes[i])); + } + + if(fields.length > 0) { + buf.append("\n" + fields.length + " fields:\n"); + for(int i=0; i < fields.length; i++) + buf.append("\t" + fields[i] + '\n'); + } + + if(methods.length > 0) { + buf.append("\n" + methods.length + " methods:\n"); + for(int i=0; i < methods.length; i++) + buf.append("\t" + methods[i] + '\n'); + } + + return buf.toString(); + } + + private static final String indent(Object obj) { + StringTokenizer tok = new StringTokenizer(obj.toString(), "\n"); + StringBuffer buf = new StringBuffer(); + + while(tok.hasMoreTokens()) + buf.append("\t" + tok.nextToken() + "\n"); + + return buf.toString(); + } + + /** + * @return deep copy of this class + */ + public JavaClass copy() { + JavaClass c = null; + + try { + c = (JavaClass)clone(); + } catch(CloneNotSupportedException e) {} + + c.constant_pool = constant_pool.copy(); + c.interfaces = (int[])interfaces.clone(); + c.interface_names = (String[])interface_names.clone(); + + c.fields = new Field[fields.length]; + for(int i=0; i < fields.length; i++) + c.fields[i] = fields[i].copy(c.constant_pool); + + c.methods = new Method[methods.length]; + for(int i=0; i < methods.length; i++) + c.methods[i] = methods[i].copy(c.constant_pool); + + c.attributes = new Attribute[attributes.length]; + for(int i=0; i < attributes.length; i++) + c.attributes[i] = attributes[i].copy(c.constant_pool); + + return c; + } + + public final boolean isSuper() { + return (access_flags & Constants.ACC_SUPER) != 0; + } + + public final boolean isClass() { + return (access_flags & Constants.ACC_INTERFACE) == 0; + } + + /** @return returns either HEAP (generated), FILE, or ZIP + */ + public final byte getSource() { + return source; + } + + /********************* New repository functionality *********************/ + + /** + * Gets the ClassRepository which holds its definition. By default + * this is the same as SyntheticRepository.getInstance(); + */ + public com.sun.org.apache.bcel.internal.util.Repository getRepository() { + return repository; + } + + /** + * Sets the ClassRepository which loaded the JavaClass. + * Should be called immediately after parsing is done. + */ + public void setRepository(com.sun.org.apache.bcel.internal.util.Repository repository) { + this.repository = repository; + } + + /** Equivalent to runtime "instanceof" operator. + * + * @return true if this JavaClass is derived from teh super class + */ + public final boolean instanceOf(JavaClass super_class) { + if(this.equals(super_class)) + return true; + + JavaClass[] super_classes = getSuperClasses(); + + for(int i=0; i < super_classes.length; i++) { + if(super_classes[i].equals(super_class)) { + return true; + } + } + + if(super_class.isInterface()) { + return implementationOf(super_class); + } + + return false; + } + + /** + * @return true, if clazz is an implementation of interface inter + */ + public boolean implementationOf(JavaClass inter) { + if(!inter.isInterface()) { + throw new IllegalArgumentException(inter.getClassName() + " is no interface"); + } + + if(this.equals(inter)) { + return true; + } + + JavaClass[] super_interfaces = getAllInterfaces(); + + for(int i=0; i < super_interfaces.length; i++) { + if(super_interfaces[i].equals(inter)) { + return true; + } + } + + return false; + } + + /** + * @return the superclass for this JavaClass object, or null if this + * is java.lang.Object + */ + public JavaClass getSuperClass() { + if("java.lang.Object".equals(getClassName())) { + return null; + } + + try { + return repository.loadClass(getSuperclassName()); + } catch(ClassNotFoundException e) { + System.err.println(e); + return null; + } + } + + /** + * @return list of super classes of this class in ascending order, i.e., + * java.lang.Object is always the last element + */ + public JavaClass[] getSuperClasses() { + JavaClass clazz = this; + ClassVector vec = new ClassVector(); + + for(clazz = clazz.getSuperClass(); clazz != null; + clazz = clazz.getSuperClass()) + { + vec.addElement(clazz); + } + + return vec.toArray(); + } + + /** + * Get interfaces directly implemented by this JavaClass. + */ + public JavaClass[] getInterfaces() { + String[] interfaces = getInterfaceNames(); + JavaClass[] classes = new JavaClass[interfaces.length]; + + try { + for(int i = 0; i < interfaces.length; i++) { + classes[i] = repository.loadClass(interfaces[i]); + } + } catch(ClassNotFoundException e) { + System.err.println(e); + return null; + } + + return classes; + } + + /** + * Get all interfaces implemented by this JavaClass (transitively). + */ + public JavaClass[] getAllInterfaces() { + ClassQueue queue = new ClassQueue(); + ClassVector vec = new ClassVector(); + + queue.enqueue(this); + + while(!queue.empty()) { + JavaClass clazz = queue.dequeue(); + + JavaClass souper = clazz.getSuperClass(); + JavaClass[] interfaces = clazz.getInterfaces(); + + if(clazz.isInterface()) { + vec.addElement(clazz); + } else { + if(souper != null) { + queue.enqueue(souper); + } + } + + for(int i = 0; i < interfaces.length; i++) { + queue.enqueue(interfaces[i]); + } + } + + return vec.toArray(); + } +} diff --git a/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/LineNumber.java b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/LineNumber.java new file mode 100644 index 00000000000..ec8b4728036 --- /dev/null +++ b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/LineNumber.java @@ -0,0 +1,167 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +package com.sun.org.apache.bcel.internal.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import com.sun.org.apache.bcel.internal.Constants; +import java.io.*; + +/** + * This class represents a (PC offset, line number) pair, i.e., a line number in + * the source that corresponds to a relative address in the byte code. This + * is used for debugging purposes. + * + * @author M. Dahm + * @see LineNumberTable + */ +public final class LineNumber implements Cloneable, Node, Serializable { + private int start_pc; // Program Counter (PC) corresponds to line + private int line_number; // number in source file + + /** + * Initialize from another object. + */ + public LineNumber(LineNumber c) { + this(c.getStartPC(), c.getLineNumber()); + } + + /** + * Construct object from file stream. + * @param file Input stream + * @throws IOException + */ + LineNumber(DataInputStream file) throws IOException + { + this(file.readUnsignedShort(), file.readUnsignedShort()); + } + + /** + * @param start_pc Program Counter (PC) corresponds to + * @param line_number line number in source file + */ + public LineNumber(int start_pc, int line_number) + { + this.start_pc = start_pc; + this.line_number = line_number; + } + + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + public void accept(Visitor v) { + v.visitLineNumber(this); + } + + /** + * Dump line number/pc pair to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + public final void dump(DataOutputStream file) throws IOException + { + file.writeShort(start_pc); + file.writeShort(line_number); + + } + /** + * @return Corresponding source line + */ + public final int getLineNumber() { return line_number; } + + /** + * @return PC in code + */ + public final int getStartPC() { return start_pc; } + + /** + * @param line_number. + */ + public final void setLineNumber(int line_number) { + this.line_number = line_number; + } + + /** + * @param start_pc. + */ + public final void setStartPC(int start_pc) { + this.start_pc = start_pc; + } + + /** + * @return String representation + */ + public final String toString() { + return "LineNumber(" + start_pc + ", " + line_number + ")"; + } + + /** + * @return deep copy of this object + */ + public LineNumber copy() { + try { + return (LineNumber)clone(); + } catch(CloneNotSupportedException e) {} + + return null; + } +} diff --git a/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/LineNumberTable.java b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/LineNumberTable.java new file mode 100644 index 00000000000..1fa9bfeaf3e --- /dev/null +++ b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/LineNumberTable.java @@ -0,0 +1,243 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +package com.sun.org.apache.bcel.internal.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import com.sun.org.apache.bcel.internal.Constants; +import java.io.*; + +/** + * This class represents a table of line numbers for debugging + * purposes. This attribute is used by the Code attribute. It + * contains pairs of PCs and line numbers. + * + * @author M. Dahm + * @see Code + * @see LineNumber + */ +public final class LineNumberTable extends Attribute { + private int line_number_table_length; + private LineNumber[] line_number_table; // Table of line/numbers pairs + + /* + * Initialize from another object. Note that both objects use the same + * references (shallow copy). Use copy() for a physical copy. + */ + public LineNumberTable(LineNumberTable c) { + this(c.getNameIndex(), c.getLength(), c.getLineNumberTable(), + c.getConstantPool()); + } + + /* + * @param name_index Index of name + * @param length Content length in bytes + * @param line_number_table Table of line/numbers pairs + * @param constant_pool Array of constants + */ + public LineNumberTable(int name_index, int length, + LineNumber[] line_number_table, + ConstantPool constant_pool) + { + super(Constants.ATTR_LINE_NUMBER_TABLE, name_index, length, constant_pool); + setLineNumberTable(line_number_table); + } + + /** + * Construct object from file stream. + * @param name_index Index of name + * @param length Content length in bytes + * @param file Input stream + * @throws IOException + * @param constant_pool Array of constants + */ + LineNumberTable(int name_index, int length, DataInputStream file, + ConstantPool constant_pool) throws IOException + { + this(name_index, length, (LineNumber[])null, constant_pool); + line_number_table_length = (file.readUnsignedShort()); + line_number_table = new LineNumber[line_number_table_length]; + + for(int i=0; i < line_number_table_length; i++) + line_number_table[i] = new LineNumber(file); + } + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + public void accept(Visitor v) { + v.visitLineNumberTable(this); + } + /** + * Dump line number table attribute to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + public final void dump(DataOutputStream file) throws IOException + { + super.dump(file); + file.writeShort(line_number_table_length); + for(int i=0; i < line_number_table_length; i++) + line_number_table[i].dump(file); + } + + /** + * @return Array of (pc offset, line number) pairs. + */ + public final LineNumber[] getLineNumberTable() { return line_number_table; } + + /** + * @param line_number_table. + */ + public final void setLineNumberTable(LineNumber[] line_number_table) { + this.line_number_table = line_number_table; + + line_number_table_length = (line_number_table == null)? 0 : + line_number_table.length; + } + + /** + * @return String representation. + */ + public final String toString() { + StringBuffer buf = new StringBuffer(); + StringBuffer line = new StringBuffer(); + + for(int i=0; i < line_number_table_length; i++) { + line.append(line_number_table[i].toString()); + + if(i < line_number_table_length - 1) + line.append(", "); + + if(line.length() > 72) { + line.append('\n'); + buf.append(line); + line.setLength(0); + } + } + + buf.append(line); + + return buf.toString(); + } + + /** + * Map byte code positions to source code lines. + * + * @param pos byte code offset + * @return corresponding line in source code + */ + public int getSourceLine(int pos) { + int l = 0, r = line_number_table_length-1; + + if(r < 0) // array is empty + return -1; + + int min_index = -1, min=-1; + + /* Do a binary search since the array is ordered. + */ + do { + int i = (l + r) / 2; + int j = line_number_table[i].getStartPC(); + + if(j == pos) + return line_number_table[i].getLineNumber(); + else if(pos < j) // else constrain search area + r = i - 1; + else // pos > j + l = i + 1; + + /* If exact match can't be found (which is the most common case) + * return the line number that corresponds to the greatest index less + * than pos. + */ + if(j < pos && j > min) { + min = j; + min_index = i; + } + } while(l <= r); + + /* It's possible that we did not find any valid entry for the bytecode + * offset we were looking for. + */ + if (min_index < 0) + return -1; + + return line_number_table[min_index].getLineNumber(); + } + + /** + * @return deep copy of this attribute + */ + public Attribute copy(ConstantPool constant_pool) { + LineNumberTable c = (LineNumberTable)clone(); + + c.line_number_table = new LineNumber[line_number_table_length]; + for(int i=0; i < line_number_table_length; i++) + c.line_number_table[i] = line_number_table[i].copy(); + + c.constant_pool = constant_pool; + return c; + } + + public final int getTableLength() { return line_number_table_length; } +} diff --git a/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/LocalVariable.java b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/LocalVariable.java new file mode 100644 index 00000000000..a80bc3bb6c4 --- /dev/null +++ b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/LocalVariable.java @@ -0,0 +1,262 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +package com.sun.org.apache.bcel.internal.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import com.sun.org.apache.bcel.internal.Constants; +import java.io.*; + +/** + * This class represents a local variable within a method. It contains its + * scope, name, signature and index on the method's frame. + * + * @author M. Dahm + * @see LocalVariableTable + */ +public final class LocalVariable + implements Constants, Cloneable, Node, Serializable +{ + private int start_pc; // Range in which the variable is valid + private int length; + private int name_index; // Index in constant pool of variable name + private int signature_index; // Index of variable signature + private int index; /* Variable is `index'th local variable on + * this method's frame. + */ + + private ConstantPool constant_pool; + + /** + * Initialize from another object. Note that both objects use the same + * references (shallow copy). Use copy() for a physical copy. + */ + public LocalVariable(LocalVariable c) { + this(c.getStartPC(), c.getLength(), c.getNameIndex(), + c.getSignatureIndex(), c.getIndex(), c.getConstantPool()); + } + + /** + * Construct object from file stream. + * @param file Input stream + * @throws IOException + */ + LocalVariable(DataInputStream file, ConstantPool constant_pool) + throws IOException + { + this(file.readUnsignedShort(), file.readUnsignedShort(), + file.readUnsignedShort(), file.readUnsignedShort(), + file.readUnsignedShort(), constant_pool); + } + + /** + * @param start_pc Range in which the variable + * @param length ... is valid + * @param name_index Index in constant pool of variable name + * @param signature_index Index of variable's signature + * @param index Variable is `index'th local variable on the method's frame + * @param constant_pool Array of constants + */ + public LocalVariable(int start_pc, int length, int name_index, + int signature_index, int index, + ConstantPool constant_pool) + { + this.start_pc = start_pc; + this.length = length; + this.name_index = name_index; + this.signature_index = signature_index; + this.index = index; + this.constant_pool = constant_pool; + } + + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + public void accept(Visitor v) { + v.visitLocalVariable(this); + } + + /** + * Dump local variable to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + public final void dump(DataOutputStream file) throws IOException + { + file.writeShort(start_pc); + file.writeShort(length); + file.writeShort(name_index); + file.writeShort(signature_index); + file.writeShort(index); + } + + /** + * @return Constant pool used by this object. + */ + public final ConstantPool getConstantPool() { return constant_pool; } + + /** + * @return Variable is valid within getStartPC() .. getStartPC()+getLength() + */ + public final int getLength() { return length; } + + /** + * @return Variable name. + */ + public final String getName() { + ConstantUtf8 c; + + c = (ConstantUtf8)constant_pool.getConstant(name_index, CONSTANT_Utf8); + return c.getBytes(); + } + + /** + * @return Index in constant pool of variable name. + */ + public final int getNameIndex() { return name_index; } + + /** + * @return Signature. + */ + public final String getSignature() { + ConstantUtf8 c; + c = (ConstantUtf8)constant_pool.getConstant(signature_index, + CONSTANT_Utf8); + return c.getBytes(); + } + + /** + * @return Index in constant pool of variable signature. + */ + public final int getSignatureIndex() { return signature_index; } + + /** + * @return index of register where variable is stored + */ + public final int getIndex() { return index; } + + /** + * @return Start of range where he variable is valid + */ + public final int getStartPC() { return start_pc; } + + /** + * @param constant_pool Constant pool to be used for this object. + */ + public final void setConstantPool(ConstantPool constant_pool) { + this.constant_pool = constant_pool; + } + + /** + * @param length. + */ + public final void setLength(int length) { + this.length = length; + } + + /** + * @param name_index. + */ + public final void setNameIndex(int name_index) { + this.name_index = name_index; + } + + /** + * @param signature_index. + */ + public final void setSignatureIndex(int signature_index) { + this.signature_index = signature_index; + } + + /** + * @param index. + */ + public final void setIndex(int index) { this.index = index; } + + /** + * @param start_pc Specify range where the local variable is valid. + */ + public final void setStartPC(int start_pc) { + this.start_pc = start_pc; + } + + /** + * @return string representation. + */ + public final String toString() { + String name = getName(), signature = Utility.signatureToString(getSignature()); + + return "LocalVariable(start_pc = " + start_pc + ", length = " + length + + ", index = " + index + ":" + signature + " " + name + ")"; + } + + /** + * @return deep copy of this object + */ + public LocalVariable copy() { + try { + return (LocalVariable)clone(); + } catch(CloneNotSupportedException e) {} + + return null; + } +} diff --git a/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/LocalVariableTable.java b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/LocalVariableTable.java new file mode 100644 index 00000000000..db0631f5b89 --- /dev/null +++ b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/LocalVariableTable.java @@ -0,0 +1,199 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +package com.sun.org.apache.bcel.internal.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import com.sun.org.apache.bcel.internal.Constants; +import java.io.*; + +/** + * This class represents colection of local variables in a + * method. This attribute is contained in the Code attribute. + * + * @author M. Dahm + * @see Code + * @see LocalVariable + */ +public class LocalVariableTable extends Attribute { + private int local_variable_table_length; // Table of local + private LocalVariable[] local_variable_table; // variables + + /** + * Initialize from another object. Note that both objects use the same + * references (shallow copy). Use copy() for a physical copy. + */ + public LocalVariableTable(LocalVariableTable c) { + this(c.getNameIndex(), c.getLength(), c.getLocalVariableTable(), + c.getConstantPool()); + } + + /** + * @param name_index Index in constant pool to `LocalVariableTable' + * @param length Content length in bytes + * @param local_variable_table Table of local variables + * @param constant_pool Array of constants + */ + public LocalVariableTable(int name_index, int length, + LocalVariable[] local_variable_table, + ConstantPool constant_pool) + { + super(Constants.ATTR_LOCAL_VARIABLE_TABLE, name_index, length, constant_pool); + setLocalVariableTable(local_variable_table); + } + + /** + * Construct object from file stream. + * @param name_index Index in constant pool + * @param length Content length in bytes + * @param file Input stream + * @param constant_pool Array of constants + * @throws IOException + */ + LocalVariableTable(int name_index, int length, DataInputStream file, + ConstantPool constant_pool) throws IOException + { + this(name_index, length, (LocalVariable[])null, constant_pool); + + local_variable_table_length = (file.readUnsignedShort()); + local_variable_table = new LocalVariable[local_variable_table_length]; + + for(int i=0; i < local_variable_table_length; i++) + local_variable_table[i] = new LocalVariable(file, constant_pool); + } + + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + public void accept(Visitor v) { + v.visitLocalVariableTable(this); + } + + /** + * Dump local variable table attribute to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + public final void dump(DataOutputStream file) throws IOException + { + super.dump(file); + file.writeShort(local_variable_table_length); + for(int i=0; i < local_variable_table_length; i++) + local_variable_table[i].dump(file); + } + + /** + * @return Array of local variables of method. + */ + public final LocalVariable[] getLocalVariableTable() { + return local_variable_table; + } + + /** @return first matching variable using index + */ + public final LocalVariable getLocalVariable(int index) { + for(int i=0; i < local_variable_table_length; i++) + if(local_variable_table[i].getIndex() == index) + return local_variable_table[i]; + + return null; + } + + public final void setLocalVariableTable(LocalVariable[] local_variable_table) + { + this.local_variable_table = local_variable_table; + local_variable_table_length = (local_variable_table == null)? 0 : + local_variable_table.length; + } + + /** + * @return String representation. + */ + public final String toString() { + StringBuffer buf = new StringBuffer(""); + + for(int i=0; i < local_variable_table_length; i++) { + buf.append(local_variable_table[i].toString()); + + if(i < local_variable_table_length - 1) + buf.append('\n'); + } + + return buf.toString(); + } + + /** + * @return deep copy of this attribute + */ + public Attribute copy(ConstantPool constant_pool) { + LocalVariableTable c = (LocalVariableTable)clone(); + + c.local_variable_table = new LocalVariable[local_variable_table_length]; + for(int i=0; i < local_variable_table_length; i++) + c.local_variable_table[i] = local_variable_table[i].copy(); + + c.constant_pool = constant_pool; + return c; + } + + public final int getTableLength() { return local_variable_table_length; } +} diff --git a/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/Method.java b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/Method.java new file mode 100644 index 00000000000..63d7689e5f0 --- /dev/null +++ b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/Method.java @@ -0,0 +1,231 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +package com.sun.org.apache.bcel.internal.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +import com.sun.org.apache.bcel.internal.Constants; +import com.sun.org.apache.bcel.internal.generic.Type; +import java.io.*; + +/** + * This class represents the method info structure, i.e., the representation + * for a method in the class. See JVM specification for details. + * A method has access flags, a name, a signature and a number of attributes. + * + * @author M. Dahm + */ +public final class Method extends FieldOrMethod { + /** + * Empty constructor, all attributes have to be defined via `setXXX' + * methods. Use at your own risk. + */ + public Method() {} + + /** + * Initialize from another object. Note that both objects use the same + * references (shallow copy). Use clone() for a physical copy. + */ + public Method(Method c) { + super(c); + } + + /** + * Construct object from file stream. + * @param file Input stream + * @throws IOException + * @throws ClassFormatException + */ + Method(DataInputStream file, ConstantPool constant_pool) + throws IOException, ClassFormatException + { + super(file, constant_pool); + } + + /** + * @param access_flags Access rights of method + * @param name_index Points to field name in constant pool + * @param signature_index Points to encoded signature + * @param attributes Collection of attributes + * @param constant_pool Array of constants + */ + public Method(int access_flags, int name_index, int signature_index, + Attribute[] attributes, ConstantPool constant_pool) + { + super(access_flags, name_index, signature_index, attributes, constant_pool); + } + + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + public void accept(Visitor v) { + v.visitMethod(this); + } + + /** + * @return Code attribute of method, if any + */ + public final Code getCode() { + for(int i=0; i < attributes_count; i++) + if(attributes[i] instanceof Code) + return (Code)attributes[i]; + + return null; + } + + /** + * @return ExceptionTable attribute of method, if any, i.e., list all + * exceptions the method may throw not exception handlers! + */ + public final ExceptionTable getExceptionTable() { + for(int i=0; i < attributes_count; i++) + if(attributes[i] instanceof ExceptionTable) + return (ExceptionTable)attributes[i]; + + return null; + } + + /** @return LocalVariableTable of code attribute if any, i.e. the call is forwarded + * to the Code atribute. + */ + public final LocalVariableTable getLocalVariableTable() { + Code code = getCode(); + + if(code != null) + return code.getLocalVariableTable(); + else + return null; + } + + /** @return LineNumberTable of code attribute if any, i.e. the call is forwarded + * to the Code atribute. + */ + public final LineNumberTable getLineNumberTable() { + Code code = getCode(); + + if(code != null) + return code.getLineNumberTable(); + else + return null; + } + + /** + * Return string representation close to declaration format, + * `public static void _main(String[] args) throws IOException', e.g. + * + * @return String representation of the method. + */ + public final String toString() { + ConstantUtf8 c; + String name, signature, access; // Short cuts to constant pool + StringBuffer buf; + + access = Utility.accessToString(access_flags); + + // Get name and signature from constant pool + c = (ConstantUtf8)constant_pool.getConstant(signature_index, + Constants.CONSTANT_Utf8); + signature = c.getBytes(); + + c = (ConstantUtf8)constant_pool.getConstant(name_index, Constants.CONSTANT_Utf8); + name = c.getBytes(); + + signature = Utility.methodSignatureToString(signature, name, access, true, + getLocalVariableTable()); + buf = new StringBuffer(signature); + + for(int i=0; i < attributes_count; i++) { + Attribute a = attributes[i]; + + if(!((a instanceof Code) || (a instanceof ExceptionTable))) + buf.append(" [" + a.toString() + "]"); + } + + ExceptionTable e = getExceptionTable(); + if(e != null) { + String str = e.toString(); + if(!str.equals("")) + buf.append("\n\t\tthrows " + str); + } + + return buf.toString(); + } + + /** + * @return deep copy of this method + */ + public final Method copy(ConstantPool constant_pool) { + return (Method)copy_(constant_pool); + } + + /** + * @return return type of method + */ + public Type getReturnType() { + return Type.getReturnType(getSignature()); + } + + /** + * @return array of method argument types + */ + public Type[] getArgumentTypes() { + return Type.getArgumentTypes(getSignature()); + } +} diff --git a/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/Node.java b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/Node.java new file mode 100644 index 00000000000..8d239c4949a --- /dev/null +++ b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/Node.java @@ -0,0 +1,68 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +package com.sun.org.apache.bcel.internal.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +/** + * Denote class to have an accept method(); + * + * @author M. Dahm + */ +public interface Node { + public void accept(Visitor obj); +} diff --git a/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/PMGClass.java b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/PMGClass.java new file mode 100644 index 00000000000..999d876bb3b --- /dev/null +++ b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/PMGClass.java @@ -0,0 +1,192 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +package com.sun.org.apache.bcel.internal.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import com.sun.org.apache.bcel.internal.Constants; +import java.io.*; + +/** + * This class is derived from Attribute and represents a reference + * to a PMG + * attribute. + * + * @author M. Dahm + * @see Attribute + */ +public final class PMGClass extends Attribute { + private int pmg_class_index, pmg_index; + + /** + * Initialize from another object. Note that both objects use the same + * references (shallow copy). Use clone() for a physical copy. + */ + public PMGClass(PMGClass c) { + this(c.getNameIndex(), c.getLength(), c.getPMGIndex(), c.getPMGClassIndex(), + c.getConstantPool()); + } + + /** + * Construct object from file stream. + * @param name_index Index in constant pool to CONSTANT_Utf8 + * @param length Content length in bytes + * @param file Input stream + * @param constant_pool Array of constants + * @throws IOException + */ + PMGClass(int name_index, int length, DataInputStream file, + ConstantPool constant_pool) throws IOException + { + this(name_index, length, file.readUnsignedShort(), file.readUnsignedShort(), + constant_pool); + } + + /** + * @param name_index Index in constant pool to CONSTANT_Utf8 + * @param length Content length in bytes + * @param constant_pool Array of constants + * @param PMGClass_index Index in constant pool to CONSTANT_Utf8 + */ + public PMGClass(int name_index, int length, int pmg_index, int pmg_class_index, + ConstantPool constant_pool) + { + super(Constants.ATTR_PMG, name_index, length, constant_pool); + this.pmg_index = pmg_index; + this.pmg_class_index = pmg_class_index; + } + + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + public void accept(Visitor v) { + System.err.println("Visiting non-standard PMGClass object"); + } + + /** + * Dump source file attribute to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + public final void dump(DataOutputStream file) throws IOException + { + super.dump(file); + file.writeShort(pmg_index); + file.writeShort(pmg_class_index); + } + + /** + * @return Index in constant pool of source file name. + */ + public final int getPMGClassIndex() { return pmg_class_index; } + + /** + * @param PMGClass_index. + */ + public final void setPMGClassIndex(int pmg_class_index) { + this.pmg_class_index = pmg_class_index; + } + + /** + * @return Index in constant pool of source file name. + */ + public final int getPMGIndex() { return pmg_index; } + + /** + * @param PMGClass_index. + */ + public final void setPMGIndex(int pmg_index) { + this.pmg_index = pmg_index; + } + + /** + * @return PMG name. + */ + public final String getPMGName() { + ConstantUtf8 c = (ConstantUtf8)constant_pool.getConstant(pmg_index, + Constants.CONSTANT_Utf8); + return c.getBytes(); + } + + /** + * @return PMG class name. + */ + public final String getPMGClassName() { + ConstantUtf8 c = (ConstantUtf8)constant_pool.getConstant(pmg_class_index, + Constants.CONSTANT_Utf8); + return c.getBytes(); + } + + /** + * @return String representation + */ + public final String toString() { + return "PMGClass(" + getPMGName() + ", " + getPMGClassName() + ")"; + } + + /** + * @return deep copy of this attribute + */ + public Attribute copy(ConstantPool constant_pool) { + return (PMGClass)clone(); + } +} diff --git a/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/Signature.java b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/Signature.java new file mode 100644 index 00000000000..e0b9cc50c50 --- /dev/null +++ b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/Signature.java @@ -0,0 +1,299 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +package com.sun.org.apache.bcel.internal.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import com.sun.org.apache.bcel.internal.Constants; +import java.io.*; + +/** + * This class is derived from Attribute and represents a reference + * to a GJ attribute. + * + * @author M. Dahm + * @see Attribute + */ +public final class Signature extends Attribute { + private int signature_index; + + /** + * Initialize from another object. Note that both objects use the same + * references (shallow copy). Use clone() for a physical copy. + */ + public Signature(Signature c) { + this(c.getNameIndex(), c.getLength(), c.getSignatureIndex(), c.getConstantPool()); + } + + /** + * Construct object from file stream. + * @param name_index Index in constant pool to CONSTANT_Utf8 + * @param length Content length in bytes + * @param file Input stream + * @param constant_pool Array of constants + * @throws IOException + */ + Signature(int name_index, int length, DataInputStream file, + ConstantPool constant_pool) throws IOException + { + this(name_index, length, file.readUnsignedShort(), constant_pool); + } + + /** + * @param name_index Index in constant pool to CONSTANT_Utf8 + * @param length Content length in bytes + * @param constant_pool Array of constants + * @param Signature_index Index in constant pool to CONSTANT_Utf8 + */ + public Signature(int name_index, int length, int signature_index, + ConstantPool constant_pool) + { + super(Constants.ATTR_SIGNATURE, name_index, length, constant_pool); + this.signature_index = signature_index; + } + + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + public void accept(Visitor v) { + System.err.println("Visiting non-standard Signature object"); + v.visitSignature(this); + } + + /** + * Dump source file attribute to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + public final void dump(DataOutputStream file) throws IOException + { + super.dump(file); + file.writeShort(signature_index); + } + + /** + * @return Index in constant pool of source file name. + */ + public final int getSignatureIndex() { return signature_index; } + + /** + * @param Signature_index. + */ + public final void setSignatureIndex(int signature_index) { + this.signature_index = signature_index; + } + + /** + * @return GJ signature. + */ + public final String getSignature() { + ConstantUtf8 c = (ConstantUtf8)constant_pool.getConstant(signature_index, + Constants.CONSTANT_Utf8); + return c.getBytes(); + } + + /** + * Extends ByteArrayInputStream to make 'unreading' chars possible. + */ + private static final class MyByteArrayInputStream extends ByteArrayInputStream { + MyByteArrayInputStream(String data) { super(data.getBytes()); } + final int mark() { return pos; } + final String getData() { return new String(buf); } + final void reset(int p) { pos = p; } + final void unread() { if(pos > 0) pos--; } + } + + private static boolean identStart(int ch) { + return ch == 'T' || ch == 'L'; + } + + private static boolean identPart(int ch) { + return ch == '/' || ch == ';'; + } + + private static final void matchIdent(MyByteArrayInputStream in, StringBuffer buf) { + int ch; + + if((ch = in.read()) == -1) + throw new RuntimeException("Illegal signature: " + in.getData() + + " no ident, reaching EOF"); + + //System.out.println("return from ident:" + (char)ch); + + if(!identStart(ch)) { + StringBuffer buf2 = new StringBuffer(); + + int count = 1; + while(Character.isJavaIdentifierPart((char)ch)) { + buf2.append((char)ch); + count++; + ch = in.read(); + } + + if(ch == ':') { // Ok, formal parameter + in.skip("Ljava/lang/Object".length()); + buf.append(buf2); + + ch = in.read(); + in.unread(); + //System.out.println("so far:" + buf2 + ":next:" +(char)ch); + } else { + for(int i=0; i < count; i++) + in.unread(); + } + + return; + } + + StringBuffer buf2 = new StringBuffer(); + ch = in.read(); + + do { + buf2.append((char)ch); + ch = in.read(); + //System.out.println("within ident:"+ (char)ch); + + } while((ch != -1) && (Character.isJavaIdentifierPart((char)ch) || (ch == '/'))); + + buf.append(buf2.toString().replace('/', '.')); + + //System.out.println("regular return ident:"+ (char)ch + ":" + buf2); + + if(ch != -1) + in.unread(); + } + + private static final void matchGJIdent(MyByteArrayInputStream in, + StringBuffer buf) + { + int ch; + + matchIdent(in, buf); + + ch = in.read(); + if((ch == '<') || ch == '(') { // Parameterized or method + //System.out.println("Enter <"); + buf.append((char)ch); + matchGJIdent(in, buf); + + while(((ch = in.read()) != '>') && (ch != ')')) { // List of parameters + if(ch == -1) + throw new RuntimeException("Illegal signature: " + in.getData() + + " reaching EOF"); + + //System.out.println("Still no >"); + buf.append(", "); + in.unread(); + matchGJIdent(in, buf); // Recursive call + } + + //System.out.println("Exit >"); + + buf.append((char)ch); + } else + in.unread(); + + ch = in.read(); + if(identStart(ch)) { + in.unread(); + matchGJIdent(in, buf); + } else if(ch == ')') { + in.unread(); + return; + } else if(ch != ';') + throw new RuntimeException("Illegal signature: " + in.getData() + " read " + + (char)ch); + } + + public static String translate(String s) { + //System.out.println("Sig:" + s); + StringBuffer buf = new StringBuffer(); + + matchGJIdent(new MyByteArrayInputStream(s), buf); + + return buf.toString(); + } + + public static final boolean isFormalParameterList(String s) { + return s.startsWith("<") && (s.indexOf(':') > 0); + } + + public static final boolean isActualParameterList(String s) { + return s.startsWith("L") && s.endsWith(">;"); + } + + /** + * @return String representation + */ + public final String toString() { + String s = getSignature(); + + return "Signature(" + s + ")"; + } + + /** + * @return deep copy of this attribute + */ + public Attribute copy(ConstantPool constant_pool) { + return (Signature)clone(); + } +} diff --git a/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/SourceFile.java b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/SourceFile.java new file mode 100644 index 00000000000..5120cd6b2bc --- /dev/null +++ b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/SourceFile.java @@ -0,0 +1,176 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +package com.sun.org.apache.bcel.internal.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import com.sun.org.apache.bcel.internal.Constants; +import java.io.*; + +/** + * This class is derived from Attribute and represents a reference + * to the source file of this class. At most one SourceFile attribute + * should appear per classfile. The intention of this class is that it is + * instantiated from the Attribute.readAttribute() method. + * + * @author M. Dahm + * @see Attribute + */ +public final class SourceFile extends Attribute { + private int sourcefile_index; + + /** + * Initialize from another object. Note that both objects use the same + * references (shallow copy). Use clone() for a physical copy. + */ + public SourceFile(SourceFile c) { + this(c.getNameIndex(), c.getLength(), c.getSourceFileIndex(), + c.getConstantPool()); + } + + /** + * Construct object from file stream. + * @param name_index Index in constant pool to CONSTANT_Utf8 + * @param length Content length in bytes + * @param file Input stream + * @param constant_pool Array of constants + * @throws IOException + */ + SourceFile(int name_index, int length, DataInputStream file, + ConstantPool constant_pool) throws IOException + { + this(name_index, length, file.readUnsignedShort(), constant_pool); + } + + /** + * @param name_index Index in constant pool to CONSTANT_Utf8, which + * should represent the string "SourceFile". + * @param length Content length in bytes, the value should be 2. + * @param constant_pool The constant pool that this attribute is + * associated with. + * @param sourcefile_index Index in constant pool to CONSTANT_Utf8. This + * string will be interpreted as the name of the file from which this + * class was compiled. It will not be interpreted as indicating the name + * of the directory contqining the file or an absolute path; this + * information has to be supplied the consumer of this attribute - in + * many cases, the JVM. + */ + public SourceFile(int name_index, int length, int sourcefile_index, + ConstantPool constant_pool) + { + super(Constants.ATTR_SOURCE_FILE, name_index, length, constant_pool); + this.sourcefile_index = sourcefile_index; + } + + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + public void accept(Visitor v) { + v.visitSourceFile(this); + } + + /** + * Dump source file attribute to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + public final void dump(DataOutputStream file) throws IOException + { + super.dump(file); + file.writeShort(sourcefile_index); + } + + /** + * @return Index in constant pool of source file name. + */ + public final int getSourceFileIndex() { return sourcefile_index; } + + /** + * @param sourcefile_index. + */ + public final void setSourceFileIndex(int sourcefile_index) { + this.sourcefile_index = sourcefile_index; + } + + /** + * @return Source file name. + */ + public final String getSourceFileName() { + ConstantUtf8 c = (ConstantUtf8)constant_pool.getConstant(sourcefile_index, + Constants.CONSTANT_Utf8); + return c.getBytes(); + } + + /** + * @return String representation + */ + public final String toString() { + return "SourceFile(" + getSourceFileName() + ")"; + } + + /** + * @return deep copy of this attribute + */ + public Attribute copy(ConstantPool constant_pool) { + return (SourceFile)clone(); + } +} diff --git a/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/StackMap.java b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/StackMap.java new file mode 100644 index 00000000000..4d44a6f3107 --- /dev/null +++ b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/StackMap.java @@ -0,0 +1,188 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +package com.sun.org.apache.bcel.internal.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import com.sun.org.apache.bcel.internal.Constants; +import java.io.*; + +/** + * This class represents a stack map attribute used for + * preverification of Java classes for the Java 2 Micro Edition + * (J2ME). This attribute is used by the KVM and contained + * within the Code attribute of a method. See CLDC specification + * 5.3.1.2 + * + * @author M. Dahm + * @see Code + * @see StackMapEntry + * @see StackMapType + */ +public final class StackMap extends Attribute implements Node { + private int map_length; + private StackMapEntry[] map; // Table of stack map entries + + /* + * @param name_index Index of name + * @param length Content length in bytes + * @param map Table of stack map entries + * @param constant_pool Array of constants + */ + public StackMap(int name_index, int length, StackMapEntry[] map, + ConstantPool constant_pool) + { + super(Constants.ATTR_STACK_MAP, name_index, length, constant_pool); + + setStackMap(map); + } + + /** + * Construct object from file stream. + * @param name_index Index of name + * @param length Content length in bytes + * @param file Input stream + * @throws IOException + * @param constant_pool Array of constants + */ + StackMap(int name_index, int length, DataInputStream file, + ConstantPool constant_pool) throws IOException + { + this(name_index, length, (StackMapEntry[])null, constant_pool); + + map_length = file.readUnsignedShort(); + map = new StackMapEntry[map_length]; + + for(int i=0; i < map_length; i++) + map[i] = new StackMapEntry(file, constant_pool); + } + + /** + * Dump line number table attribute to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + public final void dump(DataOutputStream file) throws IOException + { + super.dump(file); + file.writeShort(map_length); + for(int i=0; i < map_length; i++) + map[i].dump(file); + } + + /** + * @return Array of stack map entries + */ + public final StackMapEntry[] getStackMap() { return map; } + + /** + * @param map Array of stack map entries + */ + public final void setStackMap(StackMapEntry[] map) { + this.map = map; + + map_length = (map == null)? 0 : map.length; + } + + /** + * @return String representation. + */ + public final String toString() { + StringBuffer buf = new StringBuffer("StackMap("); + + for(int i=0; i < map_length; i++) { + buf.append(map[i].toString()); + + if(i < map_length - 1) + buf.append(", "); + } + + buf.append(')'); + + return buf.toString(); + } + + /** + * @return deep copy of this attribute + */ + public Attribute copy(ConstantPool constant_pool) { + StackMap c = (StackMap)clone(); + + c.map = new StackMapEntry[map_length]; + for(int i=0; i < map_length; i++) + c.map[i] = map[i].copy(); + + c.constant_pool = constant_pool; + return c; + } + + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + public void accept(Visitor v) { + v.visitStackMap(this); + } + + public final int getMapLength() { return map_length; } +} diff --git a/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/StackMapEntry.java b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/StackMapEntry.java new file mode 100644 index 00000000000..5b5c46fffb7 --- /dev/null +++ b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/StackMapEntry.java @@ -0,0 +1,212 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +package com.sun.org.apache.bcel.internal.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import com.sun.org.apache.bcel.internal.Constants; +import java.io.*; + +/** + * This class represents a stack map entry recording the types of + * local variables and the the of stack items at a given byte code offset. + * See CLDC specification 5.3.1.2 + * + * @author M. Dahm + * @see StackMap + * @see StackMapType + */ +public final class StackMapEntry implements Cloneable { + private int byte_code_offset; + private int number_of_locals; + private StackMapType[] types_of_locals; + private int number_of_stack_items; + private StackMapType[] types_of_stack_items; + private ConstantPool constant_pool; + + /** + * Construct object from file stream. + * @param file Input stream + * @throws IOException + */ + StackMapEntry(DataInputStream file, ConstantPool constant_pool) throws IOException + { + this(file.readShort(), file.readShort(), null, -1, null, constant_pool); + + types_of_locals = new StackMapType[number_of_locals]; + for(int i=0; i < number_of_locals; i++) + types_of_locals[i] = new StackMapType(file, constant_pool); + + number_of_stack_items = file.readShort(); + types_of_stack_items = new StackMapType[number_of_stack_items]; + for(int i=0; i < number_of_stack_items; i++) + types_of_stack_items[i] = new StackMapType(file, constant_pool); + } + + public StackMapEntry(int byte_code_offset, int number_of_locals, + StackMapType[] types_of_locals, + int number_of_stack_items, + StackMapType[] types_of_stack_items, + ConstantPool constant_pool) { + this.byte_code_offset = byte_code_offset; + this.number_of_locals = number_of_locals; + this.types_of_locals = types_of_locals; + this.number_of_stack_items = number_of_stack_items; + this.types_of_stack_items = types_of_stack_items; + this.constant_pool = constant_pool; + } + + /** + * Dump stack map entry + * + * @param file Output file stream + * @throws IOException + */ + public final void dump(DataOutputStream file) throws IOException + { + file.writeShort(byte_code_offset); + + file.writeShort(number_of_locals); + for(int i=0; i < number_of_locals; i++) + types_of_locals[i].dump(file); + + file.writeShort(number_of_stack_items); + for(int i=0; i < number_of_stack_items; i++) + types_of_stack_items[i].dump(file); + } + + /** + * @return String representation. + */ + public final String toString() { + StringBuffer buf = new StringBuffer("(offset=" + byte_code_offset); + + if(number_of_locals > 0) { + buf.append(", locals={"); + + for(int i=0; i < number_of_locals; i++) { + buf.append(types_of_locals[i]); + if(i < number_of_locals - 1) + buf.append(", "); + } + + buf.append("}"); + } + + if(number_of_stack_items > 0) { + buf.append(", stack items={"); + + for(int i=0; i < number_of_stack_items; i++) { + buf.append(types_of_stack_items[i]); + if(i < number_of_stack_items - 1) + buf.append(", "); + } + + buf.append("}"); + } + + buf.append(")"); + + return buf.toString(); + } + + + public void setByteCodeOffset(int b) { byte_code_offset = b; } + public int getByteCodeOffset() { return byte_code_offset; } + public void setNumberOfLocals(int n) { number_of_locals = n; } + public int getNumberOfLocals() { return number_of_locals; } + public void setTypesOfLocals(StackMapType[] t) { types_of_locals = t; } + public StackMapType[] getTypesOfLocals() { return types_of_locals; } + public void setNumberOfStackItems(int n) { number_of_stack_items = n; } + public int getNumberOfStackItems() { return number_of_stack_items; } + public void setTypesOfStackItems(StackMapType[] t) { types_of_stack_items = t; } + public StackMapType[] getTypesOfStackItems() { return types_of_stack_items; } + + /** + * @return deep copy of this object + */ + public StackMapEntry copy() { + try { + return (StackMapEntry)clone(); + } catch(CloneNotSupportedException e) {} + + return null; + } + + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + public void accept(Visitor v) { + v.visitStackMapEntry(this); + } + + /** + * @return Constant pool used by this object. + */ + public final ConstantPool getConstantPool() { return constant_pool; } + + /** + * @param constant_pool Constant pool to be used for this object. + */ + public final void setConstantPool(ConstantPool constant_pool) { + this.constant_pool = constant_pool; + } +} diff --git a/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/StackMapType.java b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/StackMapType.java new file mode 100644 index 00000000000..357d53d825d --- /dev/null +++ b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/StackMapType.java @@ -0,0 +1,175 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +package com.sun.org.apache.bcel.internal.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import com.sun.org.apache.bcel.internal.Constants; +import java.io.*; + +/** + * This class represents the type of a local variable or item on stack + * used in the StackMap entries. + * + * @author M. Dahm + * @see StackMapEntry + * @see StackMap + * @see Constants + */ +public final class StackMapType implements Cloneable { + private byte type; + private int index = -1; // Index to CONSTANT_Class or offset + private ConstantPool constant_pool; + + /** + * Construct object from file stream. + * @param file Input stream + * @throws IOException + */ + StackMapType(DataInputStream file, ConstantPool constant_pool) throws IOException + { + this(file.readByte(), -1, constant_pool); + + if(hasIndex()) + setIndex(file.readShort()); + + setConstantPool(constant_pool); + } + + /** + * @param type type tag as defined in the Constants interface + * @param index index to constant pool, or byte code offset + */ + public StackMapType(byte type, int index, ConstantPool constant_pool) { + setType(type); + setIndex(index); + setConstantPool(constant_pool); + } + + public void setType(byte t) { + if((t < Constants.ITEM_Bogus) || (t > Constants.ITEM_NewObject)) + throw new RuntimeException("Illegal type for StackMapType: " + t); + type = t; + } + + public byte getType() { return type; } + public void setIndex(int t) { index = t; } + + /** @return index to constant pool if type == ITEM_Object, or offset + * in byte code, if type == ITEM_NewObject, and -1 otherwise + */ + public int getIndex() { return index; } + + /** + * Dump type entries to file. + * + * @param file Output file stream + * @throws IOException + */ + public final void dump(DataOutputStream file) throws IOException + { + file.writeByte(type); + if(hasIndex()) + file.writeShort(getIndex()); + } + + /** @return true, if type is either ITEM_Object or ITEM_NewObject + */ + public final boolean hasIndex() { + return ((type == Constants.ITEM_Object) || + (type == Constants.ITEM_NewObject)); + } + + private String printIndex() { + if(type == Constants.ITEM_Object) + return ", class=" + constant_pool.constantToString(index, Constants.CONSTANT_Class); + else if(type == Constants.ITEM_NewObject) + return ", offset=" + index; + else + return ""; + } + + /** + * @return String representation + */ + public final String toString() { + return "(type=" + Constants.ITEM_NAMES[type] + printIndex() + ")"; + } + + /** + * @return deep copy of this object + */ + public StackMapType copy() { + try { + return (StackMapType)clone(); + } catch(CloneNotSupportedException e) {} + + return null; + } + + /** + * @return Constant pool used by this object. + */ + public final ConstantPool getConstantPool() { return constant_pool; } + + /** + * @param constant_pool Constant pool to be used for this object. + */ + public final void setConstantPool(ConstantPool constant_pool) { + this.constant_pool = constant_pool; + } +} diff --git a/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/Synthetic.java b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/Synthetic.java new file mode 100644 index 00000000000..4b743a66c87 --- /dev/null +++ b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/Synthetic.java @@ -0,0 +1,179 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +package com.sun.org.apache.bcel.internal.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import com.sun.org.apache.bcel.internal.Constants; +import java.io.*; + +/** + * This class is derived from Attribute and declares this class as + * `synthetic', i.e., it needs special handling. The JVM specification + * states "A class member that does not appear in the source code must be + * marked using a Synthetic attribute." It may appear in the ClassFile + * attribute table, a field_info table or a method_info table. This class + * is intended to be instantiated from the + * Attribute.readAttribute() method. + * + * @author M. Dahm + * @see Attribute + */ +public final class Synthetic extends Attribute { + private byte[] bytes; + + /** + * Initialize from another object. Note that both objects use the same + * references (shallow copy). Use copy() for a physical copy. + */ + public Synthetic(Synthetic c) { + this(c.getNameIndex(), c.getLength(), c.getBytes(), c.getConstantPool()); + } + + /** + * @param name_index Index in constant pool to CONSTANT_Utf8, which + * should represent the string "Synthetic". + * @param length Content length in bytes - should be zero. + * @param bytes Attribute contents + * @param constant_pool The constant pool this attribute is associated + * with. + */ + public Synthetic(int name_index, int length, byte[] bytes, + ConstantPool constant_pool) + { + super(Constants.ATTR_SYNTHETIC, name_index, length, constant_pool); + this.bytes = bytes; + } + + /** + * Construct object from file stream. + * @param name_index Index in constant pool to CONSTANT_Utf8 + * @param length Content length in bytes + * @param file Input stream + * @param constant_pool Array of constants + * @throws IOException + */ + Synthetic(int name_index, int length, DataInputStream file, + ConstantPool constant_pool) throws IOException + { + this(name_index, length, (byte [])null, constant_pool); + + if(length > 0) { + bytes = new byte[length]; + file.readFully(bytes); + System.err.println("Synthetic attribute with length > 0"); + } + } + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + public void accept(Visitor v) { + v.visitSynthetic(this); + } + /** + * Dump source file attribute to file stream in binary format. + * + * @param file Output file stream + * @throws IOException + */ + public final void dump(DataOutputStream file) throws IOException + { + super.dump(file); + if(length > 0) + file.write(bytes, 0, length); + } + /** + * @return data bytes. + */ + public final byte[] getBytes() { return bytes; } + + /** + * @param bytes. + */ + public final void setBytes(byte[] bytes) { + this.bytes = bytes; + } + + /** + * @return String representation. + */ + public final String toString() { + StringBuffer buf = new StringBuffer("Synthetic"); + + if(length > 0) + buf.append(" " + Utility.toHexString(bytes)); + + return buf.toString(); + } + + /** + * @return deep copy of this attribute + */ + public Attribute copy(ConstantPool constant_pool) { + Synthetic c = (Synthetic)clone(); + + if(bytes != null) + c.bytes = (byte[])bytes.clone(); + + c.constant_pool = constant_pool; + return c; + } +} diff --git a/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/Unknown.java b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/Unknown.java new file mode 100644 index 00000000000..16fc4760fd4 --- /dev/null +++ b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/Unknown.java @@ -0,0 +1,216 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +package com.sun.org.apache.bcel.internal.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import com.sun.org.apache.bcel.internal.Constants; +import java.io.*; +import java.util.*; + +/** + * This class represents a reference to an unknown (i.e., + * application-specific) attribute of a class. It is instantiated from the + * Attribute.readAttribute() method. Applications that need to + * read in application-specific attributes should create an AttributeReader implementation and + * attach it via Attribute.addAttributeReader. + + * + * @see com.sun.org.apache.bcel.internal.classfile.Attribute + * @see com.sun.org.apache.bcel.internal.classfile.AttributeReader + * @author M. Dahm + */ +public final class Unknown extends Attribute { + private byte[] bytes; + private String name; + + private static HashMap unknown_attributes = new HashMap(); + + /** @return array of unknown attributes, but just one for each kind. + */ + static Unknown[] getUnknownAttributes() { + Unknown[] unknowns = new Unknown[unknown_attributes.size()]; + Iterator entries = unknown_attributes.values().iterator(); + + for(int i=0; entries.hasNext(); i++) + unknowns[i] = (Unknown)entries.next(); + + unknown_attributes.clear(); + return unknowns; + } + + /** + * Initialize from another object. Note that both objects use the same + * references (shallow copy). Use clone() for a physical copy. + */ + public Unknown(Unknown c) { + this(c.getNameIndex(), c.getLength(), c.getBytes(), c.getConstantPool()); + } + + /** + * Create a non-standard attribute. + * + * @param name_index Index in constant pool + * @param length Content length in bytes + * @param bytes Attribute contents + * @param constant_pool Array of constants + */ + public Unknown(int name_index, int length, byte[] bytes, + ConstantPool constant_pool) + { + super(Constants.ATTR_UNKNOWN, name_index, length, constant_pool); + this.bytes = bytes; + + name = ((ConstantUtf8)constant_pool.getConstant(name_index, + Constants.CONSTANT_Utf8)).getBytes(); + unknown_attributes.put(name, this); + } + + /** + * Construct object from file stream. + * @param name_index Index in constant pool + * @param length Content length in bytes + * @param file Input stream + * @param constant_pool Array of constants + * @throws IOException + */ + Unknown(int name_index, int length, DataInputStream file, + ConstantPool constant_pool) + throws IOException + { + this(name_index, length, (byte [])null, constant_pool); + + if(length > 0) { + bytes = new byte[length]; + file.readFully(bytes); + } + } + + /** + * Called by objects that are traversing the nodes of the tree implicitely + * defined by the contents of a Java class. I.e., the hierarchy of methods, + * fields, attributes, etc. spawns a tree of objects. + * + * @param v Visitor object + */ + public void accept(Visitor v) { + v.visitUnknown(this); + } + /** + * Dump unknown bytes to file stream. + * + * @param file Output file stream + * @throws IOException + */ + public final void dump(DataOutputStream file) throws IOException + { + super.dump(file); + if(length > 0) + file.write(bytes, 0, length); + } + /** + * @return data bytes. + */ + public final byte[] getBytes() { return bytes; } + + /** + * @return name of attribute. + */ + public final String getName() { return name; } + + /** + * @param bytes. + */ + public final void setBytes(byte[] bytes) { + this.bytes = bytes; + } + + /** + * @return String representation. + */ + public final String toString() { + if(length == 0 || bytes == null) + return "(Unknown attribute " + name + ")"; + + String hex; + if(length > 10) { + byte[] tmp = new byte[10]; + System.arraycopy(bytes, 0, tmp, 0, 10); + hex = Utility.toHexString(tmp) + "... (truncated)"; + } + else + hex = Utility.toHexString(bytes); + + return "(Unknown attribute " + name + ": " + hex + ")"; + } + + /** + * @return deep copy of this attribute + */ + public Attribute copy(ConstantPool constant_pool) { + Unknown c = (Unknown)clone(); + + if(bytes != null) + c.bytes = (byte[])bytes.clone(); + + c.constant_pool = constant_pool; + return c; + } +} diff --git a/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/Utility.java b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/Utility.java new file mode 100644 index 00000000000..9e4cddc3f37 --- /dev/null +++ b/jaxp/src/share/classes/com/sun/org/apache/bcel/internal/classfile/Utility.java @@ -0,0 +1,1397 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +package com.sun.org.apache.bcel.internal.classfile; + +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2001 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache BCEL" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache BCEL", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +import com.sun.org.apache.bcel.internal.Constants; +import com.sun.org.apache.bcel.internal.util.ByteSequence; +import java.io.*; +import java.util.ArrayList; +import java.util.zip.*; + +/** + * Utility functions that do not really belong to any class in particular. + * + * @author M. Dahm + */ +public abstract class Utility { + private static int consumed_chars; /* How many chars have been consumed + * during parsing in signatureToString(). + * Read by methodSignatureToString(). + * Set by side effect,but only internally. + */ + private static boolean wide=false; /* The `WIDE' instruction is used in the + * byte code to allow 16-bit wide indices + * for local variables. This opcode + * precedes an `ILOAD', e.g.. The opcode + * immediately following takes an extra + * byte which is combined with the + * following byte to form a + * 16-bit value. + */ + /** + * Convert bit field of flags into string such as `static final'. + * + * @param access_flags Access flags + * @return String representation of flags + */ + public static final String accessToString(int access_flags) { + return accessToString(access_flags, false); + } + + /** + * Convert bit field of flags into string such as `static final'. + * + * Special case: Classes compiled with new compilers and with the + * `ACC_SUPER' flag would be said to be "synchronized". This is + * because SUN used the same value for the flags `ACC_SUPER' and + * `ACC_SYNCHRONIZED'. + * + * @param access_flags Access flags + * @param for_class access flags are for class qualifiers ? + * @return String representation of flags + */ + public static final String accessToString(int access_flags, + boolean for_class) + { + StringBuffer buf = new StringBuffer(); + + int p = 0; + for(int i=0; p < Constants.MAX_ACC_FLAG; i++) { // Loop through known flags + p = pow2(i); + + if((access_flags & p) != 0) { + /* Special case: Classes compiled with new compilers and with the + * `ACC_SUPER' flag would be said to be "synchronized". This is + * because SUN used the same value for the flags `ACC_SUPER' and + * `ACC_SYNCHRONIZED'. + */ + if(for_class && ((p == Constants.ACC_SUPER) || (p == Constants.ACC_INTERFACE))) + continue; + + buf.append(Constants.ACCESS_NAMES[i] + " "); + } + } + + return buf.toString().trim(); + } + + /** + * @return "class" or "interface", depending on the ACC_INTERFACE flag + */ + public static final String classOrInterface(int access_flags) { + return ((access_flags & Constants.ACC_INTERFACE) != 0)? "interface" : "class"; + } + + /** + * Disassemble a byte array of JVM byte codes starting from code line + * `index' and return the disassembled string representation. Decode only + * `num' opcodes (including their operands), use -1 if you want to + * decompile everything. + * + * @param code byte code array + * @param constant_pool Array of constants + * @param index offset in `code' array + * (number of opcodes, not bytes!) + * @param length number of opcodes to decompile, -1 for all + * @param verbose be verbose, e.g. print constant pool index + * @return String representation of byte codes + */ + public static final String codeToString(byte[] code, + ConstantPool constant_pool, + int index, int length, boolean verbose) + { + StringBuffer buf = new StringBuffer(code.length * 20); // Should be sufficient + ByteSequence stream = new ByteSequence(code); + + try { + for(int i=0; i < index; i++) // Skip `index' lines of code + codeToString(stream, constant_pool, verbose); + + for(int i=0; stream.available() > 0; i++) { + if((length < 0) || (i < length)) { + String indices = fillup(stream.getIndex() + ":", 6, true, ' '); + buf.append(indices + codeToString(stream, constant_pool, verbose) + '\n'); + } + } + } catch(IOException e) { + System.out.println(buf.toString()); + e.printStackTrace(); + throw new ClassFormatException("Byte code error: " + e); + } + + return buf.toString(); + } + + public static final String codeToString(byte[] code, + ConstantPool constant_pool, + int index, int length) { + return codeToString(code, constant_pool, index, length, true); + } + + /** + * Disassemble a stream of byte codes and return the + * string representation. + * + * @param bytes stream of bytes + * @param constant_pool Array of constants + * @param verbose be verbose, e.g. print constant pool index + * @return String representation of byte code + */ + public static final String codeToString(ByteSequence bytes, + ConstantPool constant_pool, boolean verbose) + throws IOException + { + short opcode = (short)bytes.readUnsignedByte(); + int default_offset=0, low, high, npairs; + int index, vindex, constant; + int[] match, jump_table; + int no_pad_bytes=0, offset; + StringBuffer buf = new StringBuffer(Constants.OPCODE_NAMES[opcode]); + + /* Special case: Skip (0-3) padding bytes, i.e., the + * following bytes are 4-byte-aligned + */ + if((opcode == Constants.TABLESWITCH) || (opcode == Constants.LOOKUPSWITCH)) { + int remainder = bytes.getIndex() % 4; + no_pad_bytes = (remainder == 0)? 0 : 4 - remainder; + + for(int i=0; i < no_pad_bytes; i++) { + byte b; + + if((b=bytes.readByte()) != 0) + System.err.println("Warning: Padding byte != 0 in " + + Constants.OPCODE_NAMES[opcode] + ":" + b); + } + + // Both cases have a field default_offset in common + default_offset = bytes.readInt(); + } + + switch(opcode) { + /* Table switch has variable length arguments. + */ + case Constants.TABLESWITCH: + low = bytes.readInt(); + high = bytes.readInt(); + + offset = bytes.getIndex() - 12 - no_pad_bytes - 1; + default_offset += offset; + + buf.append("\tdefault = " + default_offset + ", low = " + low + + ", high = " + high + "("); + + jump_table = new int[high - low + 1]; + for(int i=0; i < jump_table.length; i++) { + jump_table[i] = offset + bytes.readInt(); + buf.append(jump_table[i]); + + if(i < jump_table.length - 1) + buf.append(", "); + } + buf.append(")"); + + break; + + /* Lookup switch has variable length arguments. + */ + case Constants.LOOKUPSWITCH: { + + npairs = bytes.readInt(); + offset = bytes.getIndex() - 8 - no_pad_bytes - 1; + + match = new int[npairs]; + jump_table = new int[npairs]; + default_offset += offset; + + buf.append("\tdefault = " + default_offset + ", npairs = " + npairs + + " ("); + + for(int i=0; i < npairs; i++) { + match[i] = bytes.readInt(); + + jump_table[i] = offset + bytes.readInt(); + + buf.append("(" + match[i] + ", " + jump_table[i] + ")"); + + if(i < npairs - 1) + buf.append(", "); + } + buf.append(")"); + } + break; + + /* Two address bytes + offset from start of byte stream form the + * jump target + */ + case Constants.GOTO: case Constants.IFEQ: case Constants.IFGE: case Constants.IFGT: + case Constants.IFLE: case Constants.IFLT: case Constants.JSR: case Constants.IFNE: + case Constants.IFNONNULL: case Constants.IFNULL: case Constants.IF_ACMPEQ: + case Constants.IF_ACMPNE: case Constants.IF_ICMPEQ: case Constants.IF_ICMPGE: case Constants.IF_ICMPGT: + case Constants.IF_ICMPLE: case Constants.IF_ICMPLT: case Constants.IF_ICMPNE: + buf.append("\t\t#" + ((bytes.getIndex() - 1) + bytes.readShort())); + break; + + /* 32-bit wide jumps + */ + case Constants.GOTO_W: case Constants.JSR_W: + buf.append("\t\t#" + ((bytes.getIndex() - 1) + bytes.readInt())); + break; + + /* Index byte references local variable (register) + */ + case Constants.ALOAD: case Constants.ASTORE: case Constants.DLOAD: case Constants.DSTORE: case Constants.FLOAD: + case Constants.FSTORE: case Constants.ILOAD: case Constants.ISTORE: case Constants.LLOAD: case Constants.LSTORE: + case Constants.RET: + if(wide) { + vindex = bytes.readUnsignedShort(); + wide=false; // Clear flag + } + else + vindex = bytes.readUnsignedByte(); + + buf.append("\t\t%" + vindex); + break; + + /* + * Remember wide byte which is used to form a 16-bit address in the + * following instruction. Relies on that the method is called again with + * the following opcode. + */ + case Constants.WIDE: + wide = true; + buf.append("\t(wide)"); + break; + + /* Array of basic type. + */ + case Constants.NEWARRAY: + buf.append("\t\t<" + Constants.TYPE_NAMES[bytes.readByte()] + ">"); + break; + + /* Access object/class fields. + */ + case Constants.GETFIELD: case Constants.GETSTATIC: case Constants.PUTFIELD: case Constants.PUTSTATIC: + index = bytes.readUnsignedShort(); + buf.append("\t\t" + + constant_pool.constantToString(index, Constants.CONSTANT_Fieldref) + + (verbose? " (" + index + ")" : "")); + break; + + /* Operands are references to classes in constant pool + */ + case Constants.NEW: + case Constants.CHECKCAST: + buf.append("\t"); + case Constants.INSTANCEOF: + index = bytes.readUnsignedShort(); + buf.append("\t<" + constant_pool.constantToString(index, + Constants.CONSTANT_Class) + + ">" + (verbose? " (" + index + ")" : "")); + break; + + /* Operands are references to methods in constant pool + */ + case Constants.INVOKESPECIAL: case Constants.INVOKESTATIC: case Constants.INVOKEVIRTUAL: + index = bytes.readUnsignedShort(); + buf.append("\t" + constant_pool.constantToString(index, + Constants.CONSTANT_Methodref) + + (verbose? " (" + index + ")" : "")); + break; + + case Constants.INVOKEINTERFACE: + index = bytes.readUnsignedShort(); + int nargs = bytes.readUnsignedByte(); // historical, redundant + buf.append("\t" + + constant_pool.constantToString(index, + Constants.CONSTANT_InterfaceMethodref) + + (verbose? " (" + index + ")\t" : "") + nargs + "\t" + + bytes.readUnsignedByte()); // Last byte is a reserved space + break; + + /* Operands are references to items in constant pool + */ + case Constants.LDC_W: case Constants.LDC2_W: + index = bytes.readUnsignedShort(); + + buf.append("\t\t" + constant_pool.constantToString + (index, constant_pool.getConstant(index).getTag()) + + (verbose? " (" + index + ")" : "")); + break; + + case Constants.LDC: + index = bytes.readUnsignedByte(); + + buf.append("\t\t" + + constant_pool.constantToString + (index, constant_pool.getConstant(index).getTag()) + + (verbose? " (" + index + ")" : "")); + break; + + /* Array of references. + */ + case Constants.ANEWARRAY: + index = bytes.readUnsignedShort(); + + buf.append("\t\t<" + compactClassName(constant_pool.getConstantString + (index, Constants.CONSTANT_Class), false) + + ">" + (verbose? " (" + index + ")": "")); + break; + + /* Multidimensional array of references. + */ + case Constants.MULTIANEWARRAY: { + index = bytes.readUnsignedShort(); + int dimensions = bytes.readUnsignedByte(); + + buf.append("\t<" + compactClassName(constant_pool.getConstantString + (index, Constants.CONSTANT_Class), false) + + ">\t" + dimensions + (verbose? " (" + index + ")" : "")); + } + break; + + /* Increment local variable. + */ + case Constants.IINC: + if(wide) { + vindex = bytes.readUnsignedShort(); + constant = bytes.readShort(); + wide = false; + } + else { + vindex = bytes.readUnsignedByte(); + constant = bytes.readByte(); + } + buf.append("\t\t%" + vindex + "\t" + constant); + break; + + default: + if(Constants.NO_OF_OPERANDS[opcode] > 0) { + for(int i=0; i < Constants.TYPE_OF_OPERANDS[opcode].length; i++) { + buf.append("\t\t"); + switch(Constants.TYPE_OF_OPERANDS[opcode][i]) { + case Constants.T_BYTE: buf.append(bytes.readByte()); break; + case Constants.T_SHORT: buf.append(bytes.readShort()); break; + case Constants.T_INT: buf.append(bytes.readInt()); break; + + default: // Never reached + System.err.println("Unreachable default case reached!"); + buf.setLength(0); + } + } + } + } + + return buf.toString(); + } + + public static final String codeToString(ByteSequence bytes, ConstantPool constant_pool) + throws IOException + { + return codeToString(bytes, constant_pool, true); + } + + /** + * Shorten long class names, java/lang/String becomes + * String. + * + * @param str The long class name + * @return Compacted class name + */ + public static final String compactClassName(String str) { + return compactClassName(str, true); + } + + /** + * Shorten long class name str, i.e., chop off the prefix, + * if the + * class name starts with this string and the flag chopit is true. + * Slashes / are converted to dots .. + * + * @param str The long class name + * @param prefix The prefix the get rid off + * @param chopit Flag that determines whether chopping is executed or not + * @return Compacted class name + */ + public static final String compactClassName(String str, + String prefix, + boolean chopit) + { + int len = prefix.length(); + + str = str.replace('/', '.'); // Is `/' on all systems, even DOS + + if(chopit) { + // If string starts with `prefix' and contains no further dots + if(str.startsWith(prefix) && + (str.substring(len).indexOf('.') == -1)) + str = str.substring(len); + } + + return str; + } + + /** + * Shorten long class names, java/lang/String becomes + * java.lang.String, + * e.g.. If chopit is true the prefix java.lang + * is also removed. + * + * @param str The long class name + * @param chopit Flag that determines whether chopping is executed or not + * @return Compacted class name + */ + public static final String compactClassName(String str, boolean chopit) { + return compactClassName(str, "java.lang.", chopit); + } + + private static final boolean is_digit(char ch) { + return (ch >= '0') && (ch <= '9'); + } + + private static final boolean is_space(char ch) { + return (ch == ' ') || (ch == '\t') || (ch == '\r') || (ch == '\n'); + } + + /** + * @return `flag' with bit `i' set to 1 + */ + public static final int setBit(int flag, int i) { + return flag | pow2(i); + } + + /** + * @return `flag' with bit `i' set to 0 + */ + public static final int clearBit(int flag, int i) { + int bit = pow2(i); + return (flag & bit) == 0? flag : flag ^ bit; + } + + /** + * @return true, if bit `i' in `flag' is set + */ + public static final boolean isSet(int flag, int i) { + return (flag & pow2(i)) != 0; + } + + /** + * Converts string containing the method return and argument types + * to a byte code method signature. + * + * @param ret Return type of method + * @param argv Types of method arguments + * @return Byte code representation of method signature + */ + public final static String methodTypeToSignature(String ret, String[] argv) + throws ClassFormatException + { + StringBuffer buf = new StringBuffer("("); + String str; + + if(argv != null) + for(int i=0; i < argv.length; i++) { + str = getSignature(argv[i]); + + if(str.endsWith("V")) // void can't be a method argument + throw new ClassFormatException("Invalid type: " + argv[i]); + + buf.append(str); + } + + str = getSignature(ret); + + buf.append(")" + str); + + return buf.toString(); + } + + /** + * @param signature Method signature + * @return Array of argument types + * @throws ClassFormatException + */ + public static final String[] methodSignatureArgumentTypes(String signature) + throws ClassFormatException + { + return methodSignatureArgumentTypes(signature, true); + } + + /** + * @param signature Method signature + * @param chopit Shorten class names ? + * @return Array of argument types + * @throws ClassFormatException + */ + public static final String[] methodSignatureArgumentTypes(String signature, + boolean chopit) + throws ClassFormatException + { + ArrayList vec = new ArrayList(); + int index; + String[] types; + + try { // Read all declarations between for `(' and `)' + if(signature.charAt(0) != '(') + throw new ClassFormatException("Invalid method signature: " + signature); + + index = 1; // current string position + + while(signature.charAt(index) != ')') { + vec.add(signatureToString(signature.substring(index), chopit)); + index += consumed_chars; // update position + } + } catch(StringIndexOutOfBoundsException e) { // Should never occur + throw new ClassFormatException("Invalid method signature: " + signature); + } + + types = new String[vec.size()]; + vec.toArray(types); + return types; + } + /** + * @param signature Method signature + * @return return type of method + * @throws ClassFormatException + */ + public static final String methodSignatureReturnType(String signature) + throws ClassFormatException + { + return methodSignatureReturnType(signature, true); + } + /** + * @param signature Method signature + * @param chopit Shorten class names ? + * @return return type of method + * @throws ClassFormatException + */ + public static final String methodSignatureReturnType(String signature, + boolean chopit) + throws ClassFormatException + { + int index; + String type; + + try { + // Read return type after `)' + index = signature.lastIndexOf(')') + 1; + type = signatureToString(signature.substring(index), chopit); + } catch(StringIndexOutOfBoundsException e) { // Should never occur + throw new ClassFormatException("Invalid method signature: " + signature); + } + + return type; + } + + /** + * Converts method signature to string with all class names compacted. + * + * @param signature to convert + * @param name of method + * @param access flags of method + * @return Human readable signature + */ + public static final String methodSignatureToString(String signature, + String name, + String access) { + return methodSignatureToString(signature, name, access, true); + } + + public static final String methodSignatureToString(String signature, + String name, + String access, + boolean chopit) { + return methodSignatureToString(signature, name, access, chopit, null); + } + + /** + * A return type signature represents the return value from a method. + * It is a series of bytes in the following grammar: + * + * ::= | V + * + * The character V indicates that the method returns no value. Otherwise, the + * signature indicates the type of the return value. + * An argument signature represents an argument passed to a method: + * + * ::= + * + * A method signature represents the arguments that the method expects, and + * the value that it returns. + * ::= () + * ::= * + * + * This method converts such a string into a Java type declaration like + * `void _main(String[])' and throws a `ClassFormatException' when the parsed + * type is invalid. + * + * @param signature Method signature + * @param name Method name + * @param access Method access rights + * @return Java type declaration + * @throws ClassFormatException + */ + public static final String methodSignatureToString(String signature, + String name, + String access, + boolean chopit, + LocalVariableTable vars) + throws ClassFormatException + { + StringBuffer buf = new StringBuffer("("); + String type; + int index; + int var_index = (access.indexOf("static") >= 0)? 0 : 1; + + try { // Read all declarations between for `(' and `)' + if(signature.charAt(0) != '(') + throw new ClassFormatException("Invalid method signature: " + signature); + + index = 1; // current string position + + while(signature.charAt(index) != ')') { + String param_type = signatureToString(signature.substring(index), chopit); + buf.append(param_type); + + if(vars != null) { + LocalVariable l = vars.getLocalVariable(var_index); + + if(l != null) + buf.append(" " + l.getName()); + } else + buf.append(" arg" + var_index); + + if("double".equals(param_type) || "long".equals(param_type)) + var_index += 2; + else + var_index++; + + buf.append(", "); + index += consumed_chars; // update position + } + + index++; // update position + + // Read return type after `)' + type = signatureToString(signature.substring(index), chopit); + + } catch(StringIndexOutOfBoundsException e) { // Should never occur + throw new ClassFormatException("Invalid method signature: " + signature); + } + + if(buf.length() > 1) // Tack off the extra ", " + buf.setLength(buf.length() - 2); + + buf.append(")"); + + return access + ((access.length() > 0)? " " : "") + // May be an empty string + type + " " + name + buf.toString(); + } + + // Guess what this does + private static final int pow2(int n) { + return 1 << n; + } + + /** + * Replace all occurences of old in str with new. + * + * @param str String to permute + * @param old String to be replaced + * @param new Replacement string + * @return new String object + */ + public static final String replace(String str, String old, String new_) { + int index, old_index; + StringBuffer buf = new StringBuffer(); + + try { + if((index = str.indexOf(old)) != -1) { // `old' found in str + old_index = 0; // String start offset + + // While we have something to replace + while((index = str.indexOf(old, old_index)) != -1) { + buf.append(str.substring(old_index, index)); // append prefix + buf.append(new_); // append replacement + + old_index = index + old.length(); // Skip `old'.length chars + } + + buf.append(str.substring(old_index)); // append rest of string + str = buf.toString(); + } + } catch(StringIndexOutOfBoundsException e) { // Should not occur + System.err.println(e); + } + + return str; + } + + /** + * Converts signature to string with all class names compacted. + * + * @param signature to convert + * @return Human readable signature + */ + public static final String signatureToString(String signature) { + return signatureToString(signature, true); + } + + /** + * The field signature represents the value of an argument to a function or + * the value of a variable. It is a series of bytes generated by the + * following grammar: + * + *
+   *  ::= 
+   *       ::= ||
+   *        ::= B|C|D|F|I|J|S|Z
+   *      ::= L;
+   *       ::= [
+   *
+   * The meaning of the base types is as follows:
+   * B byte signed byte
+   * C char character
+   * D double double precision IEEE float
+   * F float single precision IEEE float
+   * I int integer
+   * J long long integer
+   * L; ... an object of the given class
+   * S short signed short
+   * Z boolean true or false
+   * [ ... array
+   * 
+ * + * This method converts this string into a Java type declaration such as + * `String[]' and throws a `ClassFormatException' when the parsed type is + * invalid. + * + * @param signature Class signature + * @param chopit Flag that determines whether chopping is executed or not + * @return Java type declaration + * @throws ClassFormatException + */ + public static final String signatureToString(String signature, + boolean chopit) + { + consumed_chars = 1; // This is the default, read just one char like `B' + + try { + switch(signature.charAt(0)) { + case 'B' : return "byte"; + case 'C' : return "char"; + case 'D' : return "double"; + case 'F' : return "float"; + case 'I' : return "int"; + case 'J' : return "long"; + + case 'L' : { // Full class name + int index = signature.indexOf(';'); // Look for closing `;' + + if(index < 0) + throw new ClassFormatException("Invalid signature: " + signature); + + consumed_chars = index + 1; // "Lblabla;" `L' and `;' are removed + + return compactClassName(signature.substring(1, index), chopit); + } + + case 'S' : return "short"; + case 'Z' : return "boolean"; + + case '[' : { // Array declaration + int n; + StringBuffer buf, brackets; + String type; + char ch; + int consumed_chars; // Shadows global var + + brackets = new StringBuffer(); // Accumulate []'s + + // Count opening brackets and look for optional size argument + for(n=0; signature.charAt(n) == '['; n++) + brackets.append("[]"); + + consumed_chars = n; // Remember value + + // The rest of the string denotes a `' + type = signatureToString(signature.substring(n), chopit); + + Utility.consumed_chars += consumed_chars; + return type + brackets.toString(); + } + + case 'V' : return "void"; + + default : throw new ClassFormatException("Invalid signature: `" + + signature + "'"); + } + } catch(StringIndexOutOfBoundsException e) { // Should never occur + throw new ClassFormatException("Invalid signature: " + e + ":" + signature); + } + } + + /** Parse Java type such as "char", or "java.lang.String[]" and return the + * signature in byte code format, e.g. "C" or "[Ljava/lang/String;" respectively. + * + * @param type Java type + * @return byte code signature + */ + public static String getSignature(String type) { + StringBuffer buf = new StringBuffer(); + char[] chars = type.toCharArray(); + boolean char_found = false, delim = false; + int index = -1; + + loop: + for(int i=0; i < chars.length; i++) { + switch(chars[i]) { + case ' ': case '\t': case '\n': case '\r': case '\f': + if(char_found) + delim = true; + break; + + case '[': + if(!char_found) + throw new RuntimeException("Illegal type: " + type); + + index = i; + break loop; + + default: + char_found = true; + if(!delim) + buf.append(chars[i]); + } + } + + int brackets = 0; + + if(index > 0) + brackets = countBrackets(type.substring(index)); + + type = buf.toString(); + buf.setLength(0); + + for(int i=0; i < brackets; i++) + buf.append('['); + + boolean found = false; + + for(int i=Constants.T_BOOLEAN; (i <= Constants.T_VOID) && !found; i++) { + if(Constants.TYPE_NAMES[i].equals(type)) { + found = true; + buf.append(Constants.SHORT_TYPE_NAMES[i]); + } + } + + if(!found) // Class name + buf.append('L' + type.replace('.', '/') + ';'); + + return buf.toString(); + } + + private static int countBrackets(String brackets) { + char[] chars = brackets.toCharArray(); + int count = 0; + boolean open = false; + + for(int i=0; iConstants + * + * @param signature in format described above + * @return type of method signature + * @see Constants + */ + public static final byte typeOfMethodSignature(String signature) + throws ClassFormatException + { + int index; + + try { + if(signature.charAt(0) != '(') + throw new ClassFormatException("Invalid method signature: " + signature); + + index = signature.lastIndexOf(')') + 1; + return typeOfSignature(signature.substring(index)); + } catch(StringIndexOutOfBoundsException e) { + throw new ClassFormatException("Invalid method signature: " + signature); + } + } + + /** + * Return type of signature as a byte value as defined in Constants + * + * @param signature in format described above + * @return type of signature + * @see Constants + */ + public static final byte typeOfSignature(String signature) + throws ClassFormatException + { + try { + switch(signature.charAt(0)) { + case 'B' : return Constants.T_BYTE; + case 'C' : return Constants.T_CHAR; + case 'D' : return Constants.T_DOUBLE; + case 'F' : return Constants.T_FLOAT; + case 'I' : return Constants.T_INT; + case 'J' : return Constants.T_LONG; + case 'L' : return Constants.T_REFERENCE; + case '[' : return Constants.T_ARRAY; + case 'V' : return Constants.T_VOID; + case 'Z' : return Constants.T_BOOLEAN; + case 'S' : return Constants.T_SHORT; + default: + throw new ClassFormatException("Invalid method signature: " + signature); + } + } catch(StringIndexOutOfBoundsException e) { + throw new ClassFormatException("Invalid method signature: " + signature); + } + } + + /** Map opcode names to opcode numbers. E.g., return Constants.ALOAD for "aload" + */ + public static short searchOpcode(String name) { + name = name.toLowerCase(); + + for(short i=0; i < Constants.OPCODE_NAMES.length; i++) + if(Constants.OPCODE_NAMES[i].equals(name)) + return i; + + return -1; + } + + /** + * Convert (signed) byte to (unsigned) short value, i.e., all negative + * values become positive. + */ + private static final short byteToShort(byte b) { + return (b < 0)? (short)(256 + b) : (short)b; + } + + /** Convert bytes into hexidecimal string + * + * @return bytes as hexidecimal string, e.g. 00 FA 12 ... + */ + public static final String toHexString(byte[] bytes) { + StringBuffer buf = new StringBuffer(); + + for(int i=0; i < bytes.length; i++) { + short b = byteToShort(bytes[i]); + String hex = Integer.toString(b, 0x10); + + if(b < 0x10) // just one digit, prepend '0' + buf.append('0'); + + buf.append(hex); + + if(i < bytes.length - 1) + buf.append(' '); + } + + return buf.toString(); + } + + /** + * Return a string for an integer justified left or right and filled up with + * `fill' characters if necessary. + * + * @param i integer to format + * @param length length of desired string + * @param left_justify format left or right + * @param fill fill character + * @return formatted int + */ + public static final String format(int i, int length, boolean left_justify, char fill) { + return fillup(Integer.toString(i), length, left_justify, fill); + } + + /** + * Fillup char with up to length characters with char `fill' and justify it left or right. + * + * @param str string to format + * @param length length of desired string + * @param left_justify format left or right + * @param fill fill character + * @return formatted string + */ + public static final String fillup(String str, int length, boolean left_justify, char fill) { + int len = length - str.length(); + char[] buf = new char[(len < 0)? 0 : len]; + + for(int j=0; j < buf.length; j++) + buf[j] = fill; + + if(left_justify) + return str + new String(buf); + else + return new String(buf) + str; + } + + static final boolean equals(byte[] a, byte[] b) { + int size; + + if((size=a.length) != b.length) + return false; + + for(int i=0; i < size; i++) + if(a[i] != b[i]) + return false; + + return true; + } + + public static final void printArray(PrintStream out, Object[] obj) { + out.println(printArray(obj, true)); + } + + public static final void printArray(PrintWriter out, Object[] obj) { + out.println(printArray(obj, true)); + } + + public static final String printArray(Object[] obj) { + return printArray(obj, true); + } + + public static final String printArray(Object[] obj, boolean braces) { + return printArray(obj, braces, false); + } + + public static final String printArray(Object[] obj, boolean braces, + boolean quote) { + if(obj == null) + return null; + + StringBuffer buf = new StringBuffer(); + if(braces) + buf.append('{'); + + for(int i=0; i < obj.length; i++) { + if(obj[i] != null) { + buf.append((quote? "\"" : "") + obj[i].toString() + (quote? "\"" : "")); + } else { + buf.append("null"); + } + + if(i < obj.length - 1) { + buf.append(", "); + } + } + + if(braces) + buf.append('}'); + + return buf.toString(); + } + + /** @return true, if character is one of (a, ... z, A, ... Z, 0, ... 9, _) + */ + public static boolean isJavaIdentifierPart(char ch) { + return ((ch >= 'a') && (ch <= 'z')) || + ((ch >= 'A') && (ch <= 'Z')) || + ((ch >= '0') && (ch <= '9')) || + (ch == '_'); + } + + /** Encode byte array it into Java identifier string, i.e., a string + * that only contains the following characters: (a, ... z, A, ... Z, + * 0, ... 9, _, $). The encoding algorithm itself is not too + * clever: if the current byte's ASCII value already is a valid Java + * identifier part, leave it as it is. Otherwise it writes the + * escape character($) followed by