From 5f68d9921d3f6cf0a36026e384147facc22a1956 Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Mon, 20 Feb 2012 13:11:08 -0800 Subject: [PATCH 01/43] 7147064: assert(allocates2(pc)) failed: not in CodeBuffer memory: 0xffffffff778d9d60 <= 0xffffffff778da69c Increase size of deopt_blob and uncommon_trap_blob by size of stack bang code (SPARC). Reviewed-by: azeemj, iveresov, never, phh --- hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp b/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp index 23f00a67483..f82066e4b70 100644 --- a/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp @@ -3431,6 +3431,9 @@ void SharedRuntime::generate_deopt_blob() { ResourceMark rm; // setup code generation tools int pad = VerifyThread ? 512 : 0;// Extra slop space for more verify code + if (UseStackBanging) { + pad += StackShadowPages*16 + 32; + } #ifdef _LP64 CodeBuffer buffer("deopt_blob", 2100+pad, 512); #else @@ -3650,6 +3653,9 @@ void SharedRuntime::generate_uncommon_trap_blob() { ResourceMark rm; // setup code generation tools int pad = VerifyThread ? 512 : 0; + if (UseStackBanging) { + pad += StackShadowPages*16 + 32; + } #ifdef _LP64 CodeBuffer buffer("uncommon_trap_blob", 2700+pad, 512); #else From 22db6951dc151f2963fcd0199a5969feb6979796 Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Tue, 21 Feb 2012 11:55:05 -0800 Subject: [PATCH 02/43] 7146442: assert(false) failed: bad AD file Take into account only stores captured by Initialize node. Added missing check for Top input in value() methods. Reviewed-by: never --- hotspot/src/share/vm/opto/connode.cpp | 4 ++- hotspot/src/share/vm/opto/escape.cpp | 38 +++++---------------------- 2 files changed, 9 insertions(+), 33 deletions(-) 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) { From e1675f98d471f32fcab1512b055943691b6eaa74 Mon Sep 17 00:00:00 2001 From: Dmitry Samersoff Date: Wed, 22 Feb 2012 19:43:22 +0400 Subject: [PATCH 03/43] 7110104: It should be possible to stop and start JMX Agent at runtime Added a capability to start and stop JMX Agent by jcmd Reviewed-by: acorn, mchung --- hotspot/src/share/vm/classfile/vmSymbols.hpp | 5 +- .../share/vm/services/diagnosticCommand.cpp | 189 +++++++++++++++++- .../share/vm/services/diagnosticCommand.hpp | 80 +++++++- 3 files changed, 271 insertions(+), 3 deletions(-) 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/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 From 97612e5913fa2bcfe9af8bedbb6dcd7c179f637c Mon Sep 17 00:00:00 2001 From: Erik Joelsson Date: Wed, 22 Feb 2012 09:24:35 +0100 Subject: [PATCH 04/43] 7141244: build-infra merge: Include $(SPEC) in makefiles and make variables overridable Reviewed-by: dholmes, ohrstrom, ohair, jcoomes --- hotspot/make/bsd/makefiles/buildtree.make | 3 + hotspot/make/bsd/makefiles/gcc.make | 94 ++++++++++--------- hotspot/make/bsd/makefiles/sparcWorks.make | 13 ++- hotspot/make/defs.make | 5 + hotspot/make/linux/makefiles/buildtree.make | 3 + hotspot/make/linux/makefiles/gcc.make | 37 ++++---- hotspot/make/linux/makefiles/sparcWorks.make | 13 ++- hotspot/make/solaris/makefiles/buildtree.make | 3 + hotspot/make/solaris/makefiles/gcc.make | 12 ++- .../make/solaris/makefiles/sparcWorks.make | 25 ++--- hotspot/make/windows/build.make | 4 + hotspot/make/windows/makefiles/compile.make | 12 +++ hotspot/make/windows/makefiles/defs.make | 16 ++++ 13 files changed, 149 insertions(+), 91 deletions(-) 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/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 From de52238d0661e4ddbe3a5159b6679ba47d551f56 Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Thu, 23 Feb 2012 09:53:09 -0800 Subject: [PATCH 05/43] 7148025: javac should not warn about InterrupttedException on the declaration of AutoCloseable itself Reviewed-by: mcimadamore --- langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java index deb9484bc50..ec620d228fb 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java @@ -1146,7 +1146,8 @@ public class Attr extends JCTree.Visitor { void checkAutoCloseable(DiagnosticPosition pos, Env env, Type resource) { if (!resource.isErroneous() && - types.asSuper(resource, syms.autoCloseableType.tsym) != null) { + types.asSuper(resource, syms.autoCloseableType.tsym) != null && + !types.isSameType(resource, syms.autoCloseableType)) { // Don't emit warning for AutoCloseable itself Symbol close = syms.noSymbol; boolean prevDeferDiags = log.deferDiagnostics; Queue prevDeferredDiags = log.deferredDiagnostics; From 27720df27ac017c96daa5432f5a30ca7e10ae258 Mon Sep 17 00:00:00 2001 From: Sean Coffey Date: Fri, 24 Feb 2012 09:10:27 +0000 Subject: [PATCH 06/43] 7133138: Improve io performance around timezone lookups Reviewed-by: okutsu --- .../src/build/tools/javazic/Mappings.java | 17 +++++- .../classes/sun/util/calendar/ZoneInfo.java | 52 ++++++++++++------- .../sun/util/calendar/ZoneInfoFile.java | 39 ++++++++------ 3 files changed, 71 insertions(+), 37 deletions(-) diff --git a/jdk/make/tools/src/build/tools/javazic/Mappings.java b/jdk/make/tools/src/build/tools/javazic/Mappings.java index 5e5498a675c..885b9a091b6 100644 --- a/jdk/make/tools/src/build/tools/javazic/Mappings.java +++ b/jdk/make/tools/src/build/tools/javazic/Mappings.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -26,6 +26,7 @@ package build.tools.javazic; import java.util.ArrayList; +import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -162,6 +163,20 @@ class Mappings { for (String key : toBeRemoved) { aliases.remove(key); } + // Eliminate any alias-to-alias mappings. For example, if + // there are A->B and B->C, A->B is changed to A->C. + Map newMap = new HashMap(); + for (String key : aliases.keySet()) { + String realid = aliases.get(key); + String leaf = realid; + while (aliases.get(leaf) != null) { + leaf = aliases.get(leaf); + } + if (!realid.equals(leaf)) { + newMap.put(key, leaf); + } + } + aliases.putAll(newMap); } Map getAliases() { diff --git a/jdk/src/share/classes/sun/util/calendar/ZoneInfo.java b/jdk/src/share/classes/sun/util/calendar/ZoneInfo.java index 975e3ed1087..2838be44603 100644 --- a/jdk/src/share/classes/sun/util/calendar/ZoneInfo.java +++ b/jdk/src/share/classes/sun/util/calendar/ZoneInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -79,13 +79,18 @@ public class ZoneInfo extends TimeZone { private static final int TRANSITION_NSHIFT = 12; // Flag for supporting JDK backward compatible IDs, such as "EST". - private static final boolean USE_OLDMAPPING; + static final boolean USE_OLDMAPPING; static { String oldmapping = AccessController.doPrivileged( new sun.security.action.GetPropertyAction("sun.timezone.ids.oldmapping", "false")).toLowerCase(Locale.ROOT); USE_OLDMAPPING = (oldmapping.equals("yes") || oldmapping.equals("true")); } + // IDs having conflicting data between Olson and JDK 1.1 + static final String[] conflictingIDs = { + "EST", "MST", "HST" + }; + private static final CalendarSystem gcal = CalendarSystem.getGregorianCalendar(); /** @@ -808,6 +813,16 @@ public class ZoneInfo extends TimeZone { private static SoftReference> aliasTable; + static Map getCachedAliasTable() { + Map aliases = null; + + SoftReference> cache = aliasTable; + if (cache != null) { + aliases = cache.get(); + } + return aliases; + } + /** * Returns a Map from alias time zone IDs to their standard * time zone IDs. @@ -816,23 +831,22 @@ public class ZoneInfo extends TimeZone { * to their standard time zone IDs, or null if * ZoneInfoMappings file is not available. */ - public synchronized static Map getAliasTable() { - Map aliases = null; - - SoftReference> cache = aliasTable; - if (cache != null) { - aliases = cache.get(); - if (aliases != null) { - return aliases; - } - } - - aliases = ZoneInfoFile.getZoneAliases(); - if (aliases != null) { - aliasTable = new SoftReference<>(aliases); - } - return aliases; - } + public synchronized static Map getAliasTable() { + Map aliases = getCachedAliasTable(); + if (aliases == null) { + aliases = ZoneInfoFile.getZoneAliases(); + if (aliases != null) { + if (!USE_OLDMAPPING) { + // Remove the conflicting IDs from the alias table. + for (String key : conflictingIDs) { + aliases.remove(key); + } + } + aliasTable = new SoftReference>(aliases); + } + } + return aliases; + } private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { diff --git a/jdk/src/share/classes/sun/util/calendar/ZoneInfoFile.java b/jdk/src/share/classes/sun/util/calendar/ZoneInfoFile.java index 2ad72b0e535..094c956a365 100644 --- a/jdk/src/share/classes/sun/util/calendar/ZoneInfoFile.java +++ b/jdk/src/share/classes/sun/util/calendar/ZoneInfoFile.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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 @@ -473,6 +473,8 @@ public class ZoneInfoFile { private static Map zoneInfoObjects = null; + private static final ZoneInfo GMT = new ZoneInfo("GMT", 0); + private static final String ziDir = AccessController.doPrivileged( new PrivilegedAction() { public String run() { @@ -553,8 +555,15 @@ public class ZoneInfoFile { * id. */ public static ZoneInfo getZoneInfo(String id) { + //treat GMT zone as special + if ("GMT".equals(id)) + return (ZoneInfo) GMT.clone(); ZoneInfo zi = getFromCache(id); if (zi == null) { + Map aliases = ZoneInfo.getCachedAliasTable(); + if (aliases != null && aliases.get(id) != null) { + return null; + } zi = createZoneInfo(id); if (zi == null) { return null; @@ -1031,30 +1040,26 @@ public class ZoneInfoFile { * @return the buffer, or null if any I/O error occurred. */ private static byte[] readZoneInfoFile(final String fileName) { + if (fileName.indexOf("..") >= 0) { + return null; + } byte[] buffer = null; try { buffer = AccessController.doPrivileged(new PrivilegedExceptionAction() { public byte[] run() throws IOException { File file = new File(ziDir, fileName); - if (!file.exists() || !file.isFile()) { - return null; - } - file = file.getCanonicalFile(); - String path = file.getCanonicalPath(); byte[] buf = null; - if (path != null && path.startsWith(ziDir)) { - int filesize = (int)file.length(); - if (filesize > 0) { - FileInputStream fis = new FileInputStream(file); - buf = new byte[filesize]; - try { - if (fis.read(buf) != filesize) { - throw new IOException("read error on " + fileName); - } - } finally { - fis.close(); + int filesize = (int)file.length(); + if (filesize > 0) { + FileInputStream fis = new FileInputStream(file); + buf = new byte[filesize]; + try { + if (fis.read(buf) != filesize) { + throw new IOException("read error on " + fileName); } + } finally { + fis.close(); } } return buf; From cecb6289706b78add6740af644d0d878d611962f Mon Sep 17 00:00:00 2001 From: Sean Coffey Date: Fri, 24 Feb 2012 09:17:46 +0000 Subject: [PATCH 07/43] 7144488: Infinite recursion for some equals tests in Collections Reviewed-by: alanb, dholmes, mduigou --- .../share/classes/java/util/Collections.java | 10 ++- .../java/util/Collections/EqualsTest.java | 67 +++++++++++++++++++ 2 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 jdk/test/java/util/Collections/EqualsTest.java diff --git a/jdk/src/share/classes/java/util/Collections.java b/jdk/src/share/classes/java/util/Collections.java index 04e642e1c00..d18d5682336 100644 --- a/jdk/src/share/classes/java/util/Collections.java +++ b/jdk/src/share/classes/java/util/Collections.java @@ -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 @@ -1489,6 +1489,8 @@ public class Collections { } public int hashCode() {return e.hashCode();} public boolean equals(Object o) { + if (this == o) + return true; if (!(o instanceof Map.Entry)) return false; Map.Entry t = (Map.Entry)o; @@ -1709,6 +1711,8 @@ public class Collections { } public boolean equals(Object o) { + if (this == o) + return true; synchronized (mutex) {return c.equals(o);} } public int hashCode() { @@ -1863,6 +1867,8 @@ public class Collections { } public boolean equals(Object o) { + if (this == o) + return true; synchronized (mutex) {return list.equals(o);} } public int hashCode() { @@ -2073,6 +2079,8 @@ public class Collections { } public boolean equals(Object o) { + if (this == o) + return true; synchronized (mutex) {return m.equals(o);} } public int hashCode() { diff --git a/jdk/test/java/util/Collections/EqualsTest.java b/jdk/test/java/util/Collections/EqualsTest.java new file mode 100644 index 00000000000..2c76751b820 --- /dev/null +++ b/jdk/test/java/util/Collections/EqualsTest.java @@ -0,0 +1,67 @@ +/* + * 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. + * + * 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. + */ + +/* + * @test + * @bug 7144488 + * @summary Infinite recursion for some equals tests in Collections + */ + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class EqualsTest { + public static void main(String[] args) { + boolean test; + + /* synchronizedList test */ + List list = Collections.synchronizedList(new ArrayList()); + list.add(list); + test = list.equals(list); + assertTrue(test); + list.remove(list); + + /* synchronizedSet test */ + Set s = Collections.synchronizedSet(new HashSet()); + s.add(s); + test = s.equals(s); + assertTrue(test); + + /* synchronizedMap test */ + Map m = Collections.synchronizedMap(new HashMap()); + test = m.equals(m); + assertTrue(test); + + } + + private static void assertTrue(boolean b) { + if (!b) + throw new RuntimeException("assertion failed"); + } +} + From 8694cd7c6253e76588b75dd4c8553f19a04103b3 Mon Sep 17 00:00:00 2001 From: Phil Race Date: Fri, 24 Feb 2012 09:37:01 -0800 Subject: [PATCH 08/43] 7147584: Changing to Nimbus/GTK in SwingSet2 on Solaris 10 Sparc causes malformed menus/layout Reviewed-by: igor, jgodinez --- jdk/src/share/classes/sun/font/SunFontManager.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/jdk/src/share/classes/sun/font/SunFontManager.java b/jdk/src/share/classes/sun/font/SunFontManager.java index bb069a3a06c..aa3f556b968 100644 --- a/jdk/src/share/classes/sun/font/SunFontManager.java +++ b/jdk/src/share/classes/sun/font/SunFontManager.java @@ -2619,10 +2619,6 @@ public abstract class SunFontManager implements FontSupport, FontManagerForSGE { physicalFonts.remove(oldFont.fullName); fullNameToFont.remove(oldFont.fullName.toLowerCase(Locale.ENGLISH)); FontFamily.remove(oldFont); - if (oldFont instanceof FileFont) { - ((FileFont)oldFont).deregisterFontAndClearStrikeCache(); - } - if (localeFullNamesToFont != null) { Map.Entry[] mapEntries = (Map.Entry[])localeFullNamesToFont.entrySet(). From a46962c4c1ba6d84ec759a5244e7baf18f5643cc Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Fri, 24 Feb 2012 10:40:32 -0800 Subject: [PATCH 09/43] 7137836: tidy up Names.java Reviewed-by: mcimadamore --- .../com/sun/tools/javac/util/Names.java | 360 ++++++++++-------- 1 file changed, 195 insertions(+), 165 deletions(-) diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/Names.java b/langtools/src/share/classes/com/sun/tools/javac/util/Names.java index f0c07ca87c4..4e6f453225f 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/util/Names.java +++ b/langtools/src/share/classes/com/sun/tools/javac/util/Names.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -47,108 +47,127 @@ public class Names { return instance; } - public final Name slash; - public final Name hyphen; - public final Name T; - public final Name slashequals; - public final Name deprecated; - public final Name init; - public final Name clinit; - public final Name error; - public final Name any; + // operators and punctuation + public final Name asterisk; + public final Name comma; public final Name empty; + public final Name hyphen; public final Name one; public final Name period; - public final Name comma; public final Name semicolon; - public final Name asterisk; - public final Name _this; - public final Name _super; - public final Name _default; + public final Name slash; + public final Name slashequals; + + // keywords public final Name _class; - public final Name java_lang; - public final Name java_lang_Object; + public final Name _default; + public final Name _super; + public final Name _this; + + // field and method names + public final Name _name; + public final Name addSuppressed; + public final Name any; + public final Name append; + public final Name clinit; + public final Name clone; + public final Name close; + public final Name compareTo; + public final Name desiredAssertionStatus; + public final Name equals; + public final Name error; + public final Name family; + public final Name finalize; + public final Name forName; + public final Name getClass; + public final Name getClassLoader; + public final Name getComponentType; + public final Name getDeclaringClass; + public final Name getMessage; + public final Name hasNext; + public final Name hashCode; + public final Name init; + public final Name initCause; + public final Name iterator; + public final Name length; + public final Name next; + public final Name ordinal; + public final Name serialVersionUID; + public final Name toString; + public final Name value; + public final Name valueOf; + public final Name values; + + // class names + public final Name java_io_Serializable; + public final Name java_lang_AutoCloseable; public final Name java_lang_Class; public final Name java_lang_Cloneable; - public final Name java_io_Serializable; - public final Name serialVersionUID; public final Name java_lang_Enum; + public final Name java_lang_Object; public final Name java_lang_invoke_MethodHandle; - public final Name package_info; + + // names of builtin classes + public final Name Array; + public final Name Bound; + public final Name Method; + + // package names + public final Name java_lang; + + // attribute names + public final Name Annotation; + public final Name AnnotationDefault; + public final Name Bridge; + public final Name CharacterRangeTable; + public final Name Code; + public final Name CompilationID; public final Name ConstantValue; + public final Name Deprecated; + public final Name EnclosingMethod; + public final Name Enum; + public final Name Exceptions; + public final Name InnerClasses; public final Name LineNumberTable; public final Name LocalVariableTable; public final Name LocalVariableTypeTable; - public final Name CharacterRangeTable; + public final Name RuntimeInvisibleAnnotations; + public final Name RuntimeInvisibleParameterAnnotations; + public final Name RuntimeInvisibleTypeAnnotations; + public final Name RuntimeVisibleAnnotations; + public final Name RuntimeVisibleParameterAnnotations; + public final Name RuntimeVisibleTypeAnnotations; + public final Name Signature; + public final Name SourceFile; + public final Name SourceID; public final Name StackMap; public final Name StackMapTable; - public final Name SourceID; - public final Name CompilationID; - public final Name Code; - public final Name Exceptions; - public final Name SourceFile; - public final Name InnerClasses; public final Name Synthetic; - public final Name Bridge; - public final Name Deprecated; - public final Name Enum; - public final Name _name; - public final Name Signature; - public final Name Varargs; - public final Name Annotation; - public final Name RuntimeVisibleAnnotations; - public final Name RuntimeInvisibleAnnotations; - public final Name RuntimeVisibleTypeAnnotations; - public final Name RuntimeInvisibleTypeAnnotations; - public final Name RuntimeVisibleParameterAnnotations; - public final Name RuntimeInvisibleParameterAnnotations; public final Name Value; - public final Name EnclosingMethod; - public final Name desiredAssertionStatus; - public final Name append; - public final Name family; - public final Name forName; - public final Name toString; - public final Name length; - public final Name valueOf; - public final Name value; - public final Name getMessage; - public final Name getClass; - public final Name TYPE; - public final Name TYPE_USE; - public final Name TYPE_PARAMETER; - public final Name FIELD; - public final Name METHOD; - public final Name PARAMETER; - public final Name CONSTRUCTOR; - public final Name LOCAL_VARIABLE; + public final Name Varargs; + + // members of java.lang.annotation.ElementType public final Name ANNOTATION_TYPE; + public final Name CONSTRUCTOR; + public final Name FIELD; + public final Name LOCAL_VARIABLE; + public final Name METHOD; public final Name PACKAGE; - public final Name SOURCE; + public final Name PARAMETER; + public final Name TYPE; + public final Name TYPE_PARAMETER; + public final Name TYPE_USE; + + // members of java.lang.annotation.RetentionPolicy public final Name CLASS; public final Name RUNTIME; - public final Name Array; - public final Name Method; - public final Name Bound; - public final Name clone; - public final Name getComponentType; - public final Name getClassLoader; - public final Name initCause; - public final Name values; - public final Name iterator; - public final Name hasNext; - public final Name next; - public final Name AnnotationDefault; - public final Name ordinal; - public final Name equals; - public final Name hashCode; - public final Name compareTo; - public final Name getDeclaringClass; + public final Name SOURCE; + + // other identifiers + public final Name T; + public final Name deprecated; public final Name ex; - public final Name finalize; - public final Name java_lang_AutoCloseable; - public final Name close; - public final Name addSuppressed; + public final Name package_info; public final Name.Table table; @@ -156,116 +175,127 @@ public class Names { Options options = Options.instance(context); table = createTable(options); - slash = fromString("/"); - hyphen = fromString("-"); - T = fromString("T"); - slashequals = fromString("/="); - deprecated = fromString("deprecated"); - - init = fromString(""); - clinit = fromString(""); - error = fromString(""); - any = fromString(""); + // operators and punctuation + asterisk = fromString("*"); + comma = fromString(","); empty = fromString(""); + hyphen = fromString("-"); one = fromString("1"); period = fromString("."); - comma = fromString(","); semicolon = fromString(";"); - asterisk = fromString("*"); - _this = fromString("this"); - _super = fromString("super"); - _default = fromString("default"); + slash = fromString("/"); + slashequals = fromString("/="); + // keywords _class = fromString("class"); - java_lang = fromString("java.lang"); - java_lang_Object = fromString("java.lang.Object"); + _default = fromString("default"); + _super = fromString("super"); + _this = fromString("this"); + + // field and method names + _name = fromString("name"); + addSuppressed = fromString("addSuppressed"); + any = fromString(""); + append = fromString("append"); + clinit = fromString(""); + clone = fromString("clone"); + close = fromString("close"); + compareTo = fromString("compareTo"); + desiredAssertionStatus = fromString("desiredAssertionStatus"); + equals = fromString("equals"); + error = fromString(""); + family = fromString("family"); + finalize = fromString("finalize"); + forName = fromString("forName"); + getClass = fromString("getClass"); + getClassLoader = fromString("getClassLoader"); + getComponentType = fromString("getComponentType"); + getDeclaringClass = fromString("getDeclaringClass"); + getMessage = fromString("getMessage"); + hasNext = fromString("hasNext"); + hashCode = fromString("hashCode"); + init = fromString(""); + initCause = fromString("initCause"); + iterator = fromString("iterator"); + length = fromString("length"); + next = fromString("next"); + ordinal = fromString("ordinal"); + serialVersionUID = fromString("serialVersionUID"); + toString = fromString("toString"); + value = fromString("value"); + valueOf = fromString("valueOf"); + values = fromString("values"); + + // class names + java_io_Serializable = fromString("java.io.Serializable"); + java_lang_AutoCloseable = fromString("java.lang.AutoCloseable"); java_lang_Class = fromString("java.lang.Class"); java_lang_Cloneable = fromString("java.lang.Cloneable"); - java_io_Serializable = fromString("java.io.Serializable"); java_lang_Enum = fromString("java.lang.Enum"); + java_lang_Object = fromString("java.lang.Object"); java_lang_invoke_MethodHandle = fromString("java.lang.invoke.MethodHandle"); - package_info = fromString("package-info"); - serialVersionUID = fromString("serialVersionUID"); + + // names of builtin classes + Array = fromString("Array"); + Bound = fromString("Bound"); + Method = fromString("Method"); + + // package names + java_lang = fromString("java.lang"); + + // attribute names + Annotation = fromString("Annotation"); + AnnotationDefault = fromString("AnnotationDefault"); + Bridge = fromString("Bridge"); + CharacterRangeTable = fromString("CharacterRangeTable"); + Code = fromString("Code"); + CompilationID = fromString("CompilationID"); ConstantValue = fromString("ConstantValue"); + Deprecated = fromString("Deprecated"); + EnclosingMethod = fromString("EnclosingMethod"); + Enum = fromString("Enum"); + Exceptions = fromString("Exceptions"); + InnerClasses = fromString("InnerClasses"); LineNumberTable = fromString("LineNumberTable"); LocalVariableTable = fromString("LocalVariableTable"); LocalVariableTypeTable = fromString("LocalVariableTypeTable"); - CharacterRangeTable = fromString("CharacterRangeTable"); + RuntimeInvisibleAnnotations = fromString("RuntimeInvisibleAnnotations"); + RuntimeInvisibleParameterAnnotations = fromString("RuntimeInvisibleParameterAnnotations"); + RuntimeInvisibleTypeAnnotations = fromString("RuntimeInvisibleTypeAnnotations"); + RuntimeVisibleAnnotations = fromString("RuntimeVisibleAnnotations"); + RuntimeVisibleParameterAnnotations = fromString("RuntimeVisibleParameterAnnotations"); + RuntimeVisibleTypeAnnotations = fromString("RuntimeVisibleTypeAnnotations"); + Signature = fromString("Signature"); + SourceFile = fromString("SourceFile"); + SourceID = fromString("SourceID"); StackMap = fromString("StackMap"); StackMapTable = fromString("StackMapTable"); - SourceID = fromString("SourceID"); - CompilationID = fromString("CompilationID"); - Code = fromString("Code"); - Exceptions = fromString("Exceptions"); - SourceFile = fromString("SourceFile"); - InnerClasses = fromString("InnerClasses"); Synthetic = fromString("Synthetic"); - Bridge = fromString("Bridge"); - Deprecated = fromString("Deprecated"); - Enum = fromString("Enum"); - _name = fromString("name"); - Signature = fromString("Signature"); - Varargs = fromString("Varargs"); - Annotation = fromString("Annotation"); - RuntimeVisibleAnnotations = fromString("RuntimeVisibleAnnotations"); - RuntimeInvisibleAnnotations = fromString("RuntimeInvisibleAnnotations"); - RuntimeVisibleTypeAnnotations = fromString("RuntimeVisibleTypeAnnotations"); - RuntimeInvisibleTypeAnnotations = fromString("RuntimeInvisibleTypeAnnotations"); - RuntimeVisibleParameterAnnotations = fromString("RuntimeVisibleParameterAnnotations"); - RuntimeInvisibleParameterAnnotations = fromString("RuntimeInvisibleParameterAnnotations"); Value = fromString("Value"); - EnclosingMethod = fromString("EnclosingMethod"); + Varargs = fromString("Varargs"); - desiredAssertionStatus = fromString("desiredAssertionStatus"); - - append = fromString("append"); - family = fromString("family"); - forName = fromString("forName"); - toString = fromString("toString"); - length = fromString("length"); - valueOf = fromString("valueOf"); - value = fromString("value"); - getMessage = fromString("getMessage"); - getClass = fromString("getClass"); - - TYPE = fromString("TYPE"); - TYPE_USE = fromString("TYPE_USE"); - TYPE_PARAMETER = fromString("TYPE_PARAMETER"); - FIELD = fromString("FIELD"); - METHOD = fromString("METHOD"); - PARAMETER = fromString("PARAMETER"); - CONSTRUCTOR = fromString("CONSTRUCTOR"); - LOCAL_VARIABLE = fromString("LOCAL_VARIABLE"); + // members of java.lang.annotation.ElementType ANNOTATION_TYPE = fromString("ANNOTATION_TYPE"); + CONSTRUCTOR = fromString("CONSTRUCTOR"); + FIELD = fromString("FIELD"); + LOCAL_VARIABLE = fromString("LOCAL_VARIABLE"); + METHOD = fromString("METHOD"); PACKAGE = fromString("PACKAGE"); + PARAMETER = fromString("PARAMETER"); + TYPE = fromString("TYPE"); + TYPE_PARAMETER = fromString("TYPE_PARAMETER"); + TYPE_USE = fromString("TYPE_USE"); - SOURCE = fromString("SOURCE"); + // members of java.lang.annotation.RetentionPolicy CLASS = fromString("CLASS"); RUNTIME = fromString("RUNTIME"); + SOURCE = fromString("SOURCE"); - Array = fromString("Array"); - Method = fromString("Method"); - Bound = fromString("Bound"); - clone = fromString("clone"); - getComponentType = fromString("getComponentType"); - getClassLoader = fromString("getClassLoader"); - initCause = fromString("initCause"); - values = fromString("values"); - iterator = fromString("iterator"); - hasNext = fromString("hasNext"); - next = fromString("next"); - AnnotationDefault = fromString("AnnotationDefault"); - ordinal = fromString("ordinal"); - equals = fromString("equals"); - hashCode = fromString("hashCode"); - compareTo = fromString("compareTo"); - getDeclaringClass = fromString("getDeclaringClass"); + // other identifiers + T = fromString("T"); + deprecated = fromString("deprecated"); ex = fromString("ex"); - finalize = fromString("finalize"); - - java_lang_AutoCloseable = fromString("java.lang.AutoCloseable"); - close = fromString("close"); - addSuppressed = fromString("addSuppressed"); + package_info = fromString("package-info"); } protected Name.Table createTable(Options options) { From 399194bb7a06b0c9c7d0dc4457fbf3454e9592df Mon Sep 17 00:00:00 2001 From: Staffan Larsen Date: Fri, 24 Feb 2012 20:02:50 +0100 Subject: [PATCH 10/43] 7073626: RmiBootstrapTest.sh and RmiSslBootstrapTest.sh fail under Cygwin Detect and handle cygwin correctly Reviewed-by: alanb, sspitsyn --- jdk/test/ProblemList.txt | 3 --- .../jmxremote/bootstrap/GeneratePropertyPassword.sh | 9 ++++++++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/jdk/test/ProblemList.txt b/jdk/test/ProblemList.txt index b75084eb97e..2d284667df2 100644 --- a/jdk/test/ProblemList.txt +++ b/jdk/test/ProblemList.txt @@ -144,9 +144,6 @@ javax/management/loading/LibraryLoader/LibraryLoaderTest.java windows-all # 7144846 javax/management/remote/mandatory/connection/ReconnectTest.java generic-all -# 7073626 -sun/management/jmxremote/bootstrap/RmiBootstrapTest.sh windows-all -sun/management/jmxremote/bootstrap/RmiSslBootstrapTest.sh windows-all ############################################################################ diff --git a/jdk/test/sun/management/jmxremote/bootstrap/GeneratePropertyPassword.sh b/jdk/test/sun/management/jmxremote/bootstrap/GeneratePropertyPassword.sh index eef07a28655..bfb3b0d6b4f 100644 --- a/jdk/test/sun/management/jmxremote/bootstrap/GeneratePropertyPassword.sh +++ b/jdk/test/sun/management/jmxremote/bootstrap/GeneratePropertyPassword.sh @@ -1,5 +1,5 @@ # -# Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2003, 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 @@ -34,6 +34,13 @@ OS=`uname -s` UMASK=`umask` +if [[ $OS == CYGWIN_NT* ]] ; then + OS="Windows_NT" + if [ -z "$SystemRoot" ] ; then + SystemRoot=$SYSTEMROOT + fi +fi + case $OS in SunOS | Linux) PATHSEP=":" From 17f17157b9162fa2d2dc8522d2b26b98cd54c02c Mon Sep 17 00:00:00 2001 From: Staffan Larsen Date: Fri, 24 Feb 2012 20:09:49 +0100 Subject: [PATCH 11/43] 7079093: TEST_BUG: java/lang/instrument/ManifestTest.sh fails with cygwin Work around problems in some cygwin installations Reviewed-by: alanb, sspitsyn --- jdk/test/ProblemList.txt | 5 +---- jdk/test/java/lang/instrument/ManifestTest.sh | 10 +++++----- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/jdk/test/ProblemList.txt b/jdk/test/ProblemList.txt index 2d284667df2..9e18b8105c3 100644 --- a/jdk/test/ProblemList.txt +++ b/jdk/test/ProblemList.txt @@ -1,6 +1,6 @@ ########################################################################### # -# 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 @@ -125,9 +125,6 @@ # 7123972 java/lang/annotation/loaderLeak/Main.java generic-all -# 7079093 -java/lang/instrument/ManifestTest.sh windows-all - # 6944188 java/lang/management/ThreadMXBean/ThreadStateTest.java generic-all diff --git a/jdk/test/java/lang/instrument/ManifestTest.sh b/jdk/test/java/lang/instrument/ManifestTest.sh index b10e2352da4..4fbd51af158 100644 --- a/jdk/test/java/lang/instrument/ManifestTest.sh +++ b/jdk/test/java/lang/instrument/ManifestTest.sh @@ -1,5 +1,5 @@ # -# Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2008, 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 @@ -396,7 +396,7 @@ while read token; do touch $FAIL_MARKER fi - MESG=`cat expect_boot_cp_line` + MESG=`cat expect_boot_cp_line | tr -d '\n\r'` grep -s "$MESG" output.log > /dev/null result=$? if [ "$result" = 0 ]; then @@ -406,7 +406,7 @@ while read token; do touch $FAIL_MARKER fi - MESG=`cat expect_redef_line` + MESG=`cat expect_redef_line | tr -d '\n\r'` grep -s "$MESG" output.log > /dev/null result=$? if [ "$result" = 0 ]; then @@ -416,7 +416,7 @@ while read token; do touch $FAIL_MARKER fi - MESG=`cat expect_retrans_line` + MESG=`cat expect_retrans_line | tr -d '\n\r'` grep -s "$MESG" output.log > /dev/null result=$? if [ "$result" = 0 ]; then @@ -426,7 +426,7 @@ while read token; do touch $FAIL_MARKER fi - MESG=`cat expect_set_nmp_line` + MESG=`cat expect_set_nmp_line | tr -d '\n\r'` grep -s "$MESG" output.log > /dev/null result=$? if [ "$result" = 0 ]; then From 9c6ab6372fd20c930e5a3e593b0ad2bdeb635ff4 Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Fri, 24 Feb 2012 12:33:31 -0800 Subject: [PATCH 12/43] 7147416: LogCompilation tool does not work with post parse inlining Fixed few problems in LogCompilation parser. Reviewed-by: never --- .../hotspot/tools/compiler/Compilation.java | 26 ++++++++- .../sun/hotspot/tools/compiler/LogParser.java | 57 +++++++++++++++++-- 2 files changed, 77 insertions(+), 6 deletions(-) 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(); From fafe66921e8b18778f60d22e2e2986c0d803c198 Mon Sep 17 00:00:00 2001 From: Alejandro Murillo Date: Fri, 24 Feb 2012 18:14:00 -0800 Subject: [PATCH 13/43] 7148664: new hotspot build - hs24-b02 Reviewed-by: jcoomes --- hotspot/make/hotspot_version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 From 84470be57889cdb5bb6c09659c2532d15fb1af2b Mon Sep 17 00:00:00 2001 From: Krystal Mok Date: Sat, 25 Feb 2012 01:49:34 -0500 Subject: [PATCH 14/43] 7148126: ConstantPoolCacheEntry::print prints to wrong stream Should print to passed in stream not tty Reviewed-by: dholmes, never --- hotspot/src/share/vm/oops/cpCacheOop.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) 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 { From 6d519d366e5c5f158a4499518af496a612f4455d Mon Sep 17 00:00:00 2001 From: Alan Bateman Date: Sun, 26 Feb 2012 17:25:42 +0000 Subject: [PATCH 15/43] 7148921: More ProblemList updates (2/2012) Reviewed-by: chegar --- jdk/test/ProblemList.txt | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/jdk/test/ProblemList.txt b/jdk/test/ProblemList.txt index 9e18b8105c3..121307a3c50 100644 --- a/jdk/test/ProblemList.txt +++ b/jdk/test/ProblemList.txt @@ -131,6 +131,9 @@ java/lang/management/ThreadMXBean/ThreadStateTest.java generic-all # 7067973 java/lang/management/MemoryMXBean/CollectionUsageThreshold.java generic-all +# 7148492 +java/lang/management/MemoryMXBean/ResetPeakMemoryUsage.java generic-all + ############################################################################ # jdk_management @@ -179,6 +182,10 @@ java/net/InetAddress/CheckJNI.java linux-all # 7102702 java/net/PortUnreachableException/OneExceptionOnly.java windows-all +# 7148829 +sun/net/InetAddress/nameservice/simple/CacheTest.java generic-all +sun/net/InetAddress/nameservice/simple/DefaultCaching.java generic-all + ############################################################################ # jdk_io @@ -209,6 +216,9 @@ java/rmi/server/Unreferenced/finiteGCLatency/FiniteGCLatency.java generic-all # 6948101 java/rmi/transport/pinLastArguments/PinLastArguments.java generic-all +# 7146541 +java/rmi/transport/rapidExportUnexport/RapidExportUnexport.java linux-all + # 7132247 java/rmi/registry/readTest/readTest.sh windows-all @@ -319,6 +329,9 @@ sun/jvmstat/monitor/MonitoredVm/CR6672135.java generic-all tools/pack200/CommandLineTests.java generic-all tools/pack200/Pack200Test.java generic-all +# 7148499 +tools/launcher/Settings.java generic-all + ############################################################################ # jdk_util From 4012f6cd341d17488a05c66461a72ec44b743e33 Mon Sep 17 00:00:00 2001 From: Roland Westrelin Date: Mon, 27 Feb 2012 09:17:44 +0100 Subject: [PATCH 16/43] 7147740: add assertions to check stack alignment on VM entry from generated code (x64) Check stack alignment on VM entry on x64. Reviewed-by: kvn, never --- .../src/cpu/x86/vm/stubGenerator_x86_64.cpp | 16 +++++++++++ .../src/cpu/x86/vm/stubRoutines_x86_64.cpp | 1 + .../src/cpu/x86/vm/stubRoutines_x86_64.hpp | 6 ++++ hotspot/src/os/solaris/vm/os_solaris.cpp | 9 ------ hotspot/src/os/windows/vm/os_windows.cpp | 10 ------- hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp | 5 ++++ .../src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp | 5 ++++ .../os_cpu/linux_sparc/vm/os_linux_sparc.cpp | 5 ++++ .../src/os_cpu/linux_x86/vm/os_linux_x86.cpp | 8 ++++++ .../os_cpu/linux_zero/vm/os_linux_zero.cpp | 5 ++++ .../solaris_sparc/vm/os_solaris_sparc.cpp | 14 ++++++++++ .../os_cpu/solaris_x86/vm/os_solaris_x86.cpp | 14 ++++++++++ .../os_cpu/solaris_x86/vm/solaris_x86_32.il | 6 ++++ .../os_cpu/solaris_x86/vm/solaris_x86_64.il | 6 ++++ .../os_cpu/windows_x86/vm/os_windows_x86.cpp | 28 +++++++++++++++++++ .../src/share/vm/runtime/interfaceSupport.hpp | 3 ++ hotspot/src/share/vm/runtime/os.hpp | 2 ++ 17 files changed, 124 insertions(+), 19 deletions(-) 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/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/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); From c815908774045040ec49c8f563d4d1e9bcc6ebc0 Mon Sep 17 00:00:00 2001 From: Roland Westrelin Date: Mon, 27 Feb 2012 11:42:30 +0100 Subject: [PATCH 17/43] 7148486: At a method handle call returning with an exception may call the runtime with misaligned stack (x64) Stack must be realigned when calling the runtime for exception propagation at a call. Reviewed-by: kvn, never --- hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp | 22 ++++++++++++++++--- .../src/cpu/x86/vm/sharedRuntime_x86_64.cpp | 10 ++++++--- 2 files changed, 26 insertions(+), 6 deletions(-) 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..6c2a565453d 100644 --- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp @@ -3620,8 +3620,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 +3636,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 From fe4588a87ef210368b931956fb44d681a9213bb8 Mon Sep 17 00:00:00 2001 From: Dmitry Samersoff Date: Mon, 27 Feb 2012 15:21:18 +0400 Subject: [PATCH 18/43] 7110104: It should be possible to stop and start JMX Agent at runtime Added a capability to start and stop JMX Agent by jcmd Reviewed-by: acorn, mchung --- .../share/classes/sun/management/Agent.java | 206 ++++-- .../management/AgentConfigurationError.java | 6 +- .../jmxremote/ConnectorBootstrap.java | 149 +++-- .../sun/management/resources/agent.properties | 15 +- jdk/test/sun/management/AgentCheckTest.java | 10 +- .../startstop/JMXStartStopDoSomething.java | 52 ++ .../jmxremote/startstop/JMXStartStopTest.java | 181 ++++++ .../jmxremote/startstop/JMXStartStopTest.sh | 603 ++++++++++++++++++ .../jmxremote/startstop/REMOTE_TESTING.txt | 11 + .../startstop/management_cl.properties | 2 + .../startstop/management_jcmd.properties | 3 + 11 files changed, 1108 insertions(+), 130 deletions(-) create mode 100644 jdk/test/sun/management/jmxremote/startstop/JMXStartStopDoSomething.java create mode 100644 jdk/test/sun/management/jmxremote/startstop/JMXStartStopTest.java create mode 100644 jdk/test/sun/management/jmxremote/startstop/JMXStartStopTest.sh create mode 100644 jdk/test/sun/management/jmxremote/startstop/REMOTE_TESTING.txt create mode 100644 jdk/test/sun/management/jmxremote/startstop/management_cl.properties create mode 100644 jdk/test/sun/management/jmxremote/startstop/management_jcmd.properties diff --git a/jdk/src/share/classes/sun/management/Agent.java b/jdk/src/share/classes/sun/management/Agent.java index d5900930bbd..7f65e5ceb9f 100644 --- a/jdk/src/share/classes/sun/management/Agent.java +++ b/jdk/src/share/classes/sun/management/Agent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -25,30 +25,34 @@ package sun.management; -import java.io.File; -import java.io.InputStream; -import java.io.FileInputStream; import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; +import java.io.InputStream; + import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.management.ManagementFactory; + import java.text.MessageFormat; + +import java.util.MissingResourceException; import java.util.Properties; import java.util.ResourceBundle; -import java.util.MissingResourceException; -import java.lang.management.ManagementFactory; -import java.lang.reflect.Method; import javax.management.remote.JMXConnectorServer; -import sun.management.jmxremote.ConnectorBootstrap; import static sun.management.AgentConfigurationError.*; +import sun.management.jmxremote.ConnectorBootstrap; import sun.misc.VMSupport; /** * This Agent is started by the VM when -Dcom.sun.management.snmp * or -Dcom.sun.management.jmxremote is set. This class will be - * loaded by the system class loader. + * loaded by the system class loader. Also jmx framework could + * be started by jcmd */ public class Agent { // management properties @@ -69,7 +73,33 @@ public class Agent { "com.sun.management.jmxremote.localConnectorAddress"; private static final String SNMP_ADAPTOR_BOOTSTRAP_CLASS_NAME = - "sun.management.snmp.AdaptorBootstrap"; + "sun.management.snmp.AdaptorBootstrap"; + + // The only active agent allowed + private static JMXConnectorServer jmxServer = null; + + // Parse string com.sun.management.prop=xxx,com.sun.management.prop=yyyy + // and return property set if args is null or empty + // return empty property set + private static Properties parseString(String args){ + Properties argProps = new Properties(); + if (args != null) { + for (String option : args.split(",")) { + String s[] = option.split("=", 2); + String name = s[0].trim(); + String value = (s.length > 1) ? s[1].trim() : ""; + + if (!name.startsWith("com.sun.management.")) { + error(INVALID_OPTION, name); + } + + argProps.setProperty(name, value); + } + } + + return argProps; + } + // invoked by -javaagent or -Dcom.sun.management.agent.class public static void premain(String args) throws Exception { @@ -82,37 +112,104 @@ public class Agent { args = JMXREMOTE; // default to local management } - // Parse agent options into properties - - Properties arg_props = new Properties(); - if (args != null) { - String[] options = args.split(","); - for (int i=0; i= 1 && option.length <= 2) { - String name = option[0]; - String value = (option.length == 1) ? "" : option[1]; - if (name != null && name.length() > 0) { - - // Assume that any com.sun.management.* options are okay - if (name.startsWith("com.sun.management.")) { - arg_props.setProperty(name, value); - } else { - error(INVALID_OPTION, name); - } - } - } - } - } + Properties arg_props = parseString(args); // Read properties from the config file - Properties config_props = new Properties(); - String fname = arg_props.getProperty(CONFIG_FILE); - readConfiguration(fname, config_props); + Properties config_props = new Properties(); + String fname = arg_props.getProperty(CONFIG_FILE); + readConfiguration(fname, config_props); - // Arguments override config file - config_props.putAll(arg_props); - startAgent(config_props); + // Arguments override config file + config_props.putAll(arg_props); + startAgent(config_props); + } + + // jcmd ManagementAgent.start_local entry point + // Also called due to command-line via startAgent() + private static synchronized void startLocalManagementAgent(){ + Properties agentProps = VMSupport.getAgentProperties(); + + // start local connector if not started + if (agentProps.get(LOCAL_CONNECTOR_ADDRESS_PROP) == null) { + JMXConnectorServer cs = ConnectorBootstrap.startLocalConnectorServer(); + String address = cs.getAddress().toString(); + // Add the local connector address to the agent properties + agentProps.put(LOCAL_CONNECTOR_ADDRESS_PROP, address); + + try { + // export the address to the instrumentation buffer + ConnectorAddressLink.export(address); + } catch (Exception x) { + // Connector server started but unable to export address + // to instrumentation buffer - non-fatal error. + warning(EXPORT_ADDRESS_FAILED, x.getMessage()); + } + } + } + + // jcmd ManagementAgent.start entry point + // This method starts the remote JMX agent and starts neither + // the local JMX agent nor the SNMP agent + // @see #startLocalManagementAgent and also @see #startAgent. + private static synchronized void startRemoteManagementAgent(String args) throws Exception { + if (jmxServer != null) { + throw new RuntimeException(getText(INVALID_STATE, "Agent already started")); + } + + Properties argProps = parseString(args); + Properties configProps = new Properties(); + + // Load the management properties from the config file + // if config file is not specified readConfiguration implicitly + // reads /lib/management/management.properties + + String fname = System.getProperty(CONFIG_FILE); + readConfiguration(fname, configProps); + + // management properties can be overridden by system properties + // which take precedence + configProps.putAll(System.getProperties()); + + // if user specifies config file into command line for either + // jcmd utilities or attach command it overrides properties set in + // command line at the time of VM start + String fnameUser = argProps.getProperty(CONFIG_FILE); + if (fnameUser != null) { + readConfiguration(fnameUser, configProps); + } + + // arguments specified in command line of jcmd utilities + // override both system properties and one set by config file + // specified in jcmd command line + configProps.putAll(argProps); + + // jcmd doesn't allow to change ThreadContentionMonitoring, but user + // can specify this property inside config file, so enable optional + // monitoring functionality if this property is set + final String enableThreadContentionMonitoring = + configProps.getProperty(ENABLE_THREAD_CONTENTION_MONITORING); + + if (enableThreadContentionMonitoring != null) { + ManagementFactory.getThreadMXBean(). + setThreadContentionMonitoringEnabled(true); + } + + String jmxremotePort = configProps.getProperty(JMXREMOTE_PORT); + if (jmxremotePort != null) { + jmxServer = ConnectorBootstrap. + startRemoteConnectorServer(jmxremotePort, configProps); + } + } + + private static synchronized void stopRemoteManagementAgent() throws Exception { + if (jmxServer != null) { + ConnectorBootstrap.unexportRegistry(); + + // Attempt to stop already stopped agent + // Don't cause any errors. + jmxServer.stop(); + jmxServer = null; + } } private static void startAgent(Properties props) throws Exception { @@ -130,7 +227,7 @@ public class Agent { try { if (snmpPort != null) { - loadSnmpAgent(snmpPort, props); + loadSnmpAgent(snmpPort, props); } /* @@ -142,31 +239,14 @@ public class Agent { * of this "local" server is exported as a counter to the jstat * instrumentation buffer. */ - if (jmxremote != null || jmxremotePort != null) { + if (jmxremote != null || jmxremotePort != null) { if (jmxremotePort != null) { - ConnectorBootstrap.initialize(jmxremotePort, props); + jmxServer = ConnectorBootstrap. + startRemoteConnectorServer(jmxremotePort, props); } + startLocalManagementAgent(); + } - Properties agentProps = VMSupport.getAgentProperties(); - // start local connector if not started - // System.out.println("local address : " + - // agentProps.get(LOCAL_CONNECTOR_ADDRESS_PROP)); - if (agentProps.get(LOCAL_CONNECTOR_ADDRESS_PROP) == null) { - JMXConnectorServer cs = ConnectorBootstrap.startLocalConnectorServer(); - String address = cs.getAddress().toString(); - // Add the local connector address to the agent properties - agentProps.put(LOCAL_CONNECTOR_ADDRESS_PROP, address); - - try { - // export the address to the instrumentation buffer - ConnectorAddressLink.export(address); - } catch (Exception x) { - // Connector server started but unable to export address - // to instrumentation buffer - non-fatal error. - warning(EXPORT_ADDRESS_FAILED, x.getMessage()); - } - } - } } catch (AgentConfigurationError e) { error(e.getError(), e.getParams()); } catch (Exception e) { @@ -187,9 +267,9 @@ public class Agent { props.putAll(System.getProperties()); return props; - } + } - public static synchronized Properties getManagementProperties() { + public static synchronized Properties getManagementProperties() { if (mgmtProps == null) { String configFile = System.getProperty(CONFIG_FILE); String snmpPort = System.getProperty(SNMP_PORT); diff --git a/jdk/src/share/classes/sun/management/AgentConfigurationError.java b/jdk/src/share/classes/sun/management/AgentConfigurationError.java index 50370727705..601117e1bcf 100644 --- a/jdk/src/share/classes/sun/management/AgentConfigurationError.java +++ b/jdk/src/share/classes/sun/management/AgentConfigurationError.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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 @@ -53,6 +53,8 @@ public class AgentConfigurationError extends Error { "agent.err.invalid.agentclass"; public static final String INVALID_JMXREMOTE_PORT = "agent.err.invalid.jmxremote.port"; + public static final String INVALID_JMXREMOTE_RMI_PORT = + "agent.err.invalid.jmxremote.rmi.port"; public static final String PASSWORD_FILE_NOT_SET = "agent.err.password.file.notset"; public static final String PASSWORD_FILE_NOT_READABLE = @@ -105,6 +107,8 @@ public class AgentConfigurationError extends Error { "agent.err.snmp.adaptor.start.failed"; public static final String SNMP_MIB_INIT_FAILED = "agent.err.snmp.mib.init.failed"; + public static final String INVALID_STATE = + "agent.err.invalid.state"; private final String error; private final String[] params; diff --git a/jdk/src/share/classes/sun/management/jmxremote/ConnectorBootstrap.java b/jdk/src/share/classes/sun/management/jmxremote/ConnectorBootstrap.java index 710180516dc..a2f05634c62 100644 --- a/jdk/src/share/classes/sun/management/jmxremote/ConnectorBootstrap.java +++ b/jdk/src/share/classes/sun/management/jmxremote/ConnectorBootstrap.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -28,25 +28,22 @@ package sun.management.jmxremote; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; -import java.io.InputStream; import java.io.IOException; - +import java.io.InputStream; +import java.lang.management.ManagementFactory; import java.net.InetAddress; import java.net.MalformedURLException; import java.net.UnknownHostException; - import java.rmi.NoSuchObjectException; import java.rmi.Remote; import java.rmi.RemoteException; import java.rmi.registry.Registry; -import java.rmi.server.RemoteObject; import java.rmi.server.RMIClientSocketFactory; import java.rmi.server.RMIServerSocketFactory; +import java.rmi.server.RemoteObject; import java.rmi.server.UnicastRemoteObject; - import java.security.KeyStore; import java.security.Principal; - import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; @@ -55,35 +52,31 @@ import java.util.Properties; import java.util.Set; import java.util.StringTokenizer; -import java.lang.management.ManagementFactory; - -import javax.net.ssl.*; - import javax.management.MBeanServer; import javax.management.remote.JMXAuthenticator; import javax.management.remote.JMXConnectorServer; import javax.management.remote.JMXConnectorServerFactory; import javax.management.remote.JMXServiceURL; import javax.management.remote.rmi.RMIConnectorServer; - +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManagerFactory; import javax.rmi.ssl.SslRMIClientSocketFactory; import javax.rmi.ssl.SslRMIServerSocketFactory; - import javax.security.auth.Subject; -import sun.rmi.server.UnicastRef; -import sun.rmi.server.UnicastServerRef; -import sun.rmi.server.UnicastServerRef2; +import com.sun.jmx.remote.internal.RMIExporter; +import com.sun.jmx.remote.security.JMXPluggableAuthenticator; +import com.sun.jmx.remote.util.ClassLogger; import sun.management.Agent; import sun.management.AgentConfigurationError; import static sun.management.AgentConfigurationError.*; import sun.management.ConnectorAddressLink; import sun.management.FileSystem; -import com.sun.jmx.remote.util.ClassLogger; - -import com.sun.jmx.remote.internal.RMIExporter; -import com.sun.jmx.remote.security.JMXPluggableAuthenticator; +import sun.rmi.server.UnicastRef; +import sun.rmi.server.UnicastServerRef; +import sun.rmi.server.UnicastServerRef2; /** * This class initializes and starts the RMIConnectorServer for JSR 163 @@ -114,6 +107,8 @@ public final class ConnectorBootstrap { public static final String PORT = "com.sun.management.jmxremote.port"; + public static final String RMI_PORT = + "com.sun.management.jmxremote.rmi.port"; public static final String CONFIG_FILE_NAME = "com.sun.management.config.file"; public static final String USE_LOCAL_ONLY = @@ -266,34 +261,61 @@ public final class ConnectorBootstrap { private final String accessFile; } - /** - * Initializes and starts the JMX Connector Server. - * If the com.sun.management.jmxremote.port property is not defined, - * simply return. Otherwise, attempts to load the config file, and - * then calls {@link #initialize(java.lang.String, java.util.Properties)}. - * - **/ - public static synchronized JMXConnectorServer initialize() { + // The variable below is here to support stop functionality + // It would be overriten if you call startRemoteCommectionServer second + // time. It's OK for now as logic in Agent.java forbids mutiple agents + private static Registry registry = null; - // Load a new management properties - final Properties props = Agent.loadManagementProperties(); - if (props == null) { - return null; + public static void unexportRegistry() { + // Remove the entry from registry + try { + if (registry != null) { + UnicastRemoteObject.unexportObject(registry, true); + registry = null; + } + } catch(NoSuchObjectException ex) { + // This exception can appears only if we attempt + // to unexportRegistry second time. So it's safe + // to ignore it without additional messages. } + } - final String portStr = props.getProperty(PropertyNames.PORT); + /** + * Initializes and starts the JMX Connector Server. + * If the com.sun.management.jmxremote.port property is not defined, + * simply return. Otherwise, attempts to load the config file, and + * then calls {@link #startRemoteConnectorServer + * (java.lang.String, java.util.Properties)}. + * + * This method is used by some jtreg tests. + **/ + public static synchronized JMXConnectorServer initialize() { + // Load a new management properties + final Properties props = Agent.loadManagementProperties(); + if (props == null) { + return null; + } - // System.out.println("initializing: {port=" + portStr + ", - // properties="+props+"}"); - return initialize(portStr, props); + final String portStr = props.getProperty(PropertyNames.PORT); + return startRemoteConnectorServer(portStr, props); + } + + /** + * This method is used by some jtreg tests. + * + * @see #startRemoteConnectorServer + * (String portStr, Properties props) + */ + public static synchronized JMXConnectorServer initialize(String portStr, Properties props) { + return startRemoteConnectorServer(portStr, props); } /** * Initializes and starts a JMX Connector Server for remote * monitoring and management. **/ - public static synchronized JMXConnectorServer initialize(String portStr, Properties props) { + public static synchronized JMXConnectorServer startRemoteConnectorServer(String portStr, Properties props) { // Get port number final int port; @@ -306,6 +328,22 @@ public final class ConnectorBootstrap { throw new AgentConfigurationError(INVALID_JMXREMOTE_PORT, portStr); } + // User can specify a port to be used to export rmi object, + // in order to simplify firewall rules + // if port is not specified random one will be allocated. + int rmiPort = 0; + String rmiPortStr = props.getProperty(PropertyNames.RMI_PORT); + try { + if (rmiPortStr != null) { + rmiPort = Integer.parseInt(rmiPortStr); + } + } catch (NumberFormatException x) { + throw new AgentConfigurationError(INVALID_JMXREMOTE_RMI_PORT, x, rmiPortStr); + } + if (rmiPort < 0) { + throw new AgentConfigurationError(INVALID_JMXREMOTE_RMI_PORT, rmiPortStr); + } + // Do we use authentication? final String useAuthenticationStr = props.getProperty(PropertyNames.USE_AUTHENTICATION, @@ -387,9 +425,10 @@ public final class ConnectorBootstrap { } if (log.debugOn()) { - log.debug("initialize", - Agent.getText("jmxremote.ConnectorBootstrap.initialize") + + log.debug("startRemoteConnectorServer", + Agent.getText("jmxremote.ConnectorBootstrap.starting") + "\n\t" + PropertyNames.PORT + "=" + port + + "\n\t" + PropertyNames.RMI_PORT + "=" + rmiPort + "\n\t" + PropertyNames.USE_SSL + "=" + useSsl + "\n\t" + PropertyNames.USE_REGISTRY_SSL + "=" + useRegistrySsl + "\n\t" + PropertyNames.SSL_CONFIG_FILE_NAME + "=" + sslConfigFileName + @@ -404,7 +443,7 @@ public final class ConnectorBootstrap { (useAuthentication ? (loginConfigName == null ? ("\n\t" + PropertyNames.PASSWORD_FILE_NAME + "=" + passwordFileName) : ("\n\t" + PropertyNames.LOGIN_CONFIG_NAME + "=" + loginConfigName)) : "\n\t" + - Agent.getText("jmxremote.ConnectorBootstrap.initialize.noAuthentication")) + + Agent.getText("jmxremote.ConnectorBootstrap.noAuthentication")) + (useAuthentication ? ("\n\t" + PropertyNames.ACCESS_FILE_NAME + "=" + accessFileName) : "") + ""); @@ -415,15 +454,15 @@ public final class ConnectorBootstrap { JMXServiceURL url = null; try { final JMXConnectorServerData data = exportMBeanServer( - mbs, port, useSsl, useRegistrySsl, + mbs, port, rmiPort, useSsl, useRegistrySsl, sslConfigFileName, enabledCipherSuitesList, enabledProtocolsList, sslNeedClientAuth, useAuthentication, loginConfigName, passwordFileName, accessFileName); cs = data.jmxConnectorServer; url = data.jmxRemoteURL; - log.config("initialize", - Agent.getText("jmxremote.ConnectorBootstrap.initialize.ready", + log.config("startRemoteConnectorServer", + Agent.getText("jmxremote.ConnectorBootstrap.ready", url.toString())); } catch (Exception e) { throw new AgentConfigurationError(AGENT_EXCEPTION, e, e.toString()); @@ -442,7 +481,7 @@ public final class ConnectorBootstrap { // Remote connector server started but unable to export remote // connector address and associated configuration properties to // the instrumentation buffer - non-fatal error. - log.debug("initialize", e); + log.debug("startRemoteConnectorServer", e); } return cs; } @@ -517,9 +556,9 @@ public final class ConnectorBootstrap { try { if (fs.supportsFileSecurity(file)) { if (!fs.isAccessUserOnly(file)) { - final String msg = Agent.getText("jmxremote.ConnectorBootstrap.initialize.password.readonly", + final String msg = Agent.getText("jmxremote.ConnectorBootstrap.password.readonly", passwordFileName); - log.config("initialize", msg); + log.config("startRemoteConnectorServer", msg); throw new AgentConfigurationError(PASSWORD_FILE_ACCESS_NOT_RESTRICTED, passwordFileName); } @@ -560,9 +599,9 @@ public final class ConnectorBootstrap { if (fs.supportsFileSecurity(file)) { if (!fs.isAccessUserOnly(file)) { final String msg = Agent.getText( - "jmxremote.ConnectorBootstrap.initialize.file.readonly", + "jmxremote.ConnectorBootstrap.file.readonly", restrictedFileName); - log.config("initialize", msg); + log.config("startRemoteConnectorServer", msg); throw new AgentConfigurationError( FILE_ACCESS_NOT_RESTRICTED, restrictedFileName); } @@ -662,6 +701,7 @@ public final class ConnectorBootstrap { private static JMXConnectorServerData exportMBeanServer( MBeanServer mbs, int port, + int rmiPort, boolean useSsl, boolean useRegistrySsl, String sslConfigFileName, @@ -679,7 +719,7 @@ public final class ConnectorBootstrap { * IDs. */ System.setProperty("java.rmi.server.randomIDs", "true"); - JMXServiceURL url = new JMXServiceURL("rmi", null, 0); + JMXServiceURL url = new JMXServiceURL("rmi", null, rmiPort); Map env = new HashMap<>(); @@ -736,7 +776,6 @@ public final class ConnectorBootstrap { } } - final Registry registry; if (useRegistrySsl) { registry = new SingleEntryRegistry(port, csf, ssf, @@ -747,10 +786,12 @@ public final class ConnectorBootstrap { "jmxrmi", exporter.firstExported); } - JMXServiceURL remoteURL = new JMXServiceURL( - "service:jmx:rmi:///jndi/rmi://" + url.getHost() + ":" + - ((UnicastRef) ((RemoteObject) registry).getRef()).getLiveRef().getPort() + - "/jmxrmi"); + + int registryPort = + ((UnicastRef) ((RemoteObject) registry).getRef()).getLiveRef().getPort(); + String jmxUrlStr = String.format("service:jmx:rmi:///jndi/rmi://%s:%d/jmxrmi", + url.getHost(), registryPort); + JMXServiceURL remoteURL = new JMXServiceURL(jmxUrlStr); /* Our exporter remembers the first object it was asked to export, which will be an RMIServerImpl appropriate for diff --git a/jdk/src/share/classes/sun/management/resources/agent.properties b/jdk/src/share/classes/sun/management/resources/agent.properties index 88c3b46beef..3ca238670dd 100644 --- a/jdk/src/share/classes/sun/management/resources/agent.properties +++ b/jdk/src/share/classes/sun/management/resources/agent.properties @@ -1,6 +1,6 @@ # # -# Copyright (c) 2004, 2005, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2004, 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 @@ -43,8 +43,9 @@ agent.err.agentclass.failed = Management agent class failed agent.err.premain.notfound = premain(String) does not exist in agent class agent.err.agentclass.access.denied = Access to premain(String) is denied agent.err.invalid.agentclass = Invalid com.sun.management.agent.class property value - +agent.err.invalid.state = Invalid agent state agent.err.invalid.jmxremote.port = Invalid com.sun.management.jmxremote.port number +agent.err.invalid.jmxremote.rmi.port = Invalid com.sun.management.jmxremote.rmi.port number agent.err.file.not.set = File not specified agent.err.file.not.readable = File not readable @@ -78,11 +79,11 @@ agent.err.acl.file.access.notrestricted = Password file read access must be rest agent.err.snmp.adaptor.start.failed = Failed to start SNMP adaptor with address agent.err.snmp.mib.init.failed = Failed to initialize SNMP MIB with error -jmxremote.ConnectorBootstrap.initialize = Starting JMX Connector Server: -jmxremote.ConnectorBootstrap.initialize.noAuthentication = No Authentication -jmxremote.ConnectorBootstrap.initialize.ready = JMX Connector ready at: {0} -jmxremote.ConnectorBootstrap.initialize.password.readonly = Password file read access must be restricted: {0} -jmxremote.ConnectorBootstrap.initialize.file.readonly = File read access must be restricted: {0} +jmxremote.ConnectorBootstrap.starting = Starting JMX Connector Server: +jmxremote.ConnectorBootstrap.noAuthentication = No Authentication +jmxremote.ConnectorBootstrap.ready = JMX Connector ready at: {0} +jmxremote.ConnectorBootstrap.password.readonly = Password file read access must be restricted: {0} +jmxremote.ConnectorBootstrap.file.readonly = File read access must be restricted: {0} jmxremote.AdaptorBootstrap.getTargetList.processing = Processing ACL jmxremote.AdaptorBootstrap.getTargetList.adding = Adding target: {0} diff --git a/jdk/test/sun/management/AgentCheckTest.java b/jdk/test/sun/management/AgentCheckTest.java index 4f4ba90e4de..1e5a27c60b5 100644 --- a/jdk/test/sun/management/AgentCheckTest.java +++ b/jdk/test/sun/management/AgentCheckTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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 @@ -35,10 +35,10 @@ public class AgentCheckTest { public static void main(String[] args){ String [][] testStrings = { {"agent.err.error", "", ""}, - {"jmxremote.ConnectorBootstrap.initialize", "", ""}, - {"jmxremote.ConnectorBootstrap.initialize.noAuthentication", "", ""}, - {"jmxremote.ConnectorBootstrap.initialize.ready", "Phony JMXServiceURL", ""}, - {"jmxremote.ConnectorBootstrap.initialize.password.readonly", "Phony passwordFileName", ""}, + {"jmxremote.ConnectorBootstrap.starting", "", ""}, + {"jmxremote.ConnectorBootstrap.noAuthentication", "", ""}, + {"jmxremote.ConnectorBootstrap.ready", "Phony JMXServiceURL", ""}, + {"jmxremote.ConnectorBootstrap.password.readonly", "Phony passwordFileName", ""}, {"jmxremote.AdaptorBootstrap.getTargetList.processing", "", ""}, {"jmxremote.AdaptorBootstrap.getTargetList.adding", "Phony target", ""}, {"jmxremote.AdaptorBootstrap.getTargetList.starting", "", ""}, diff --git a/jdk/test/sun/management/jmxremote/startstop/JMXStartStopDoSomething.java b/jdk/test/sun/management/jmxremote/startstop/JMXStartStopDoSomething.java new file mode 100644 index 00000000000..39b04562958 --- /dev/null +++ b/jdk/test/sun/management/jmxremote/startstop/JMXStartStopDoSomething.java @@ -0,0 +1,52 @@ +/* + * 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. + * + * 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. + */ + +import java.io.RandomAccessFile; + +public class JMXStartStopDoSomething { + + + public void doSomething(){ + try { + for (int i=0; i < 10; ++i) { + RandomAccessFile f = new RandomAccessFile("/dev/null","r"); + int n = f.read(); + f.close(); + } + + } catch (Throwable e) { + System.err.println("Something bad happens:" +e); + } + } + + public static void main(String args[]) throws Exception { + System.err.println("main enter"); + int count = 1; + while(count > 0) { + JMXStartStopDoSomething p = new JMXStartStopDoSomething(); + p.doSomething(); + Thread.sleep(1); + } + // System.err.println("main exit"); + } +} diff --git a/jdk/test/sun/management/jmxremote/startstop/JMXStartStopTest.java b/jdk/test/sun/management/jmxremote/startstop/JMXStartStopTest.java new file mode 100644 index 00000000000..1a14ee0a08b --- /dev/null +++ b/jdk/test/sun/management/jmxremote/startstop/JMXStartStopTest.java @@ -0,0 +1,181 @@ +/* + * 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. + * + * 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. + */ + +import java.io.File; +import java.io.FileInputStream; +import java.io.FilenameFilter; +import java.io.IOException; +import java.io.InputStream; +import java.rmi.registry.LocateRegistry; +import java.rmi.registry.Registry; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Properties; +import java.util.Set; + +import javax.management.*; +import javax.management.remote.*; + +import sun.management.AgentConfigurationError; +import sun.management.jmxremote.ConnectorBootstrap; + +public class JMXStartStopTest { + + static boolean verbose = false; + + static void dbg_print(String msg){ + if (verbose) { + System.err.println("DBG: " +msg); + } + } + + static void dbg_print(String msg, Throwable ex){ + if (verbose) { + System.err.println("DBG: " + msg + " " + ex.getMessage() ); + ex.printStackTrace(System.err); + } + } + + public static int listMBeans(MBeanServerConnection server, ObjectName pattern, QueryExp query) + throws Exception { + + Set names = server.queryNames(pattern,query); + for (Iterator i=names.iterator(); i.hasNext(); ) { + ObjectName name = (ObjectName)i.next(); + MBeanInfo info = server.getMBeanInfo(name); + dbg_print("Got MBean: " + name); + + MBeanAttributeInfo[] attrs = info.getAttributes(); + if (attrs == null) + continue; + + for (int j=0; j 0) { + port = Integer.parseInt(args[0]); + } + dbg_print("Using port: " + port); + + int rmiPort = 0; + if (args != null && args.length > 1) { + rmiPort = Integer.parseInt(args[1]); + } + dbg_print("Using rmi port: " + rmiPort); + + Registry registry = LocateRegistry.getRegistry(port); + + // "jmxrmi" + String[] relist = registry.list(); + for (int i = 0; i < relist.length; ++i) { + dbg_print("Got registry: " + relist[i]); + } + + String jmxUrlStr = (rmiPort != 0) ? + String.format("service:jmx:rmi://localhost:%d/jndi/rmi://localhost:%d/jmxrmi", rmiPort, port) : + String.format("service:jmx:rmi:///jndi/rmi://localhost:%d/jmxrmi",port); + + JMXServiceURL url = new JMXServiceURL(jmxUrlStr); + Map m = new HashMap(); + + JMXConnector c = JMXConnectorFactory.connect(url,m); + + MBeanServerConnection conn = c.getMBeanServerConnection(); + ObjectName pattern = new ObjectName("java.lang:type=Memory,*"); + + int count = listMBeans(conn,pattern,null); + if (count == 0) + throw new Exception("Expected at least one matching "+ "MBean for "+pattern); + } + + + public static void main(String args[]) { + JMXStartStopTest manager = new JMXStartStopTest(); + try { + if (args!=null && args[0].equals("local")) { + manager.run_local(args[1]); + } else { + manager.run(args); + } + } catch (RuntimeException r) { + dbg_print("No connection: ", r); + System.out.println("NO_CONN"); + System.exit(1); + } catch (Throwable t) { + dbg_print("No connection: ", t); + System.out.println("NO_CONN"); + System.exit(2); + } + System.out.println("OK_CONN"); + System.exit(0); + } + +} diff --git a/jdk/test/sun/management/jmxremote/startstop/JMXStartStopTest.sh b/jdk/test/sun/management/jmxremote/startstop/JMXStartStopTest.sh new file mode 100644 index 00000000000..d575cfd612e --- /dev/null +++ b/jdk/test/sun/management/jmxremote/startstop/JMXStartStopTest.sh @@ -0,0 +1,603 @@ +#!/bin/sh + +# 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 +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# 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. + +# @test +# @bug 7110104 +# @build JMXStartStopTest JMXStartStopDoSomething +# @run shell JMXStartStopTest.sh --jtreg --no-compile +# @summary No word Failed expected in the test output + +_verbose=no +_server=no +_jtreg=no +_compile=yes +_testsuite="01,02,03,04,05,06,07,08,09,10,11,12,13" +_port_one=50234 +_port_two=50235 + + +_testclasses=".classes" +_testsrc=`pwd` + +_logname=".classes/JMXStartStopTest_output.txt" + + +_compile(){ + + if [ ! -e ${_testclasses} ] + then + mkdir -p ${_testclasses} + fi + + rm -f ${_testclasses}/JMXStartStopTest.class + + # Compile testcase + ${TESTJAVA}/bin/javac -d ${_testclasses} JMXStartStopDoSomething.java JMXStartStopTest.java + + if [ ! -e ${_testclasses}/JMXStartStopTest.class ] + then + echo "ERROR: Can't compile" + exit -1 + fi +} + +_app_start(){ + + if [ "${_verbose}" = "yes" ] + then + echo "RUN: ${TESTJAVA}/bin/java -server $* -cp ${_testclasses} JMXStartStopDoSomething " + fi + ${TESTJAVA}/bin/java -server $* -cp ${_testclasses} JMXStartStopDoSomething >> ${_logname} 2>&1 & + sleep 1 + + pid=`_get_pid` + if [ "x${pid}" = "x" ] + then + echo "ERROR: Test app not started" + exit -1 + fi + +} + +_get_pid(){ + ${TESTJAVA}/bin/jps | sed -n "/JMXStartStopDoSomething/s/ .*//p" +} + +_app_stop(){ + pid=`_get_pid` + if [ "x${pid}" != "x" ] + then + kill $pid + fi + + # Stop on first failed test under jtreg + if [ "x$1" = "xFailed" -a "${_jtreg}" = "yes" ] + then + exit -1 + fi +} + +testme(){ + ${TESTJAVA}/bin/java -cp ${_testclasses} JMXStartStopTest $* +} + + +_jcmd(){ + if [ "${_verbose}" = "yes" ] + then + echo "RUN: ${TESTJAVA}/bin/jcmd JMXStartStopDoSomething $*" + ${TESTJAVA}/bin/jcmd JMXStartStopDoSomething $* + else + ${TESTJAVA}/bin/jcmd JMXStartStopDoSomething $* > /dev/null 2>/dev/null + fi +} + +_echo(){ + echo "$*" + echo "$*" >> ${_logname} +} + +# ============= TESTS ====================================== + +test_01(){ +# Run an app with JMX enabled stop it and +# restart on other port + + _echo "**** Test one ****" + + _app_start -Dcom.sun.management.jmxremote.port=$1 \ + -Dcom.sun.management.jmxremote.authenticate=false \ + -Dcom.sun.management.jmxremote.ssl=false + + res1=`testme $1` + + _jcmd ManagementAgent.stop + + res2=`testme $1` + + _jcmd ManagementAgent.start jmxremote.port=$2 + + res3=`testme $2` + + + if [ "${res1}" = "OK_CONN" -a "${res2}" = "NO_CONN" -a "${res3}" = "OK_CONN" ] + then + _echo "Passed" + else + _echo "Failed r1(OK):${res1} r2(NO):${res2} r3(OK):${res3}" + _app_stop "Failed" + fi + + _app_stop + +} + +test_02(){ +# Run an app without JMX enabled +# start JMX by jcmd + +_echo "**** Test two ****" +_app_start + +_jcmd ManagementAgent.start jmxremote.port=$1 jmxremote.authenticate=false jmxremote.ssl=false + +res1=`testme $1` + +if [ "${res1}" = "OK_CONN" ] +then + _echo "Passed" +else + _echo "Failed r1(OK):${res1}" + _app_stop "Failed" +fi + +_app_stop + +} + +test_03(){ +# Run an app without JMX enabled +# start JMX by jcmd on one port than on other one + +_echo "**** Test three ****" +_app_start + +_jcmd ManagementAgent.start jmxremote.port=$1 jmxremote.authenticate=false jmxremote.ssl=false + +# Second agent shouldn't start +_jcmd ManagementAgent.start jmxremote.port=$2 jmxremote.authenticate=false jmxremote.ssl=false + +# First agent should connect +res1=`testme $1` + +if [ "${res1}" = "OK_CONN" ] +then + _echo "Passed $1" +else + _echo "Failed r1(NO):${res1}" + _app_stop "Failed" +fi + +#Second agent shouldn't connect +res1=`testme $2` + +if [ "${res1}" = "NO_CONN" ] +then + _echo "Passed $2" +else + _echo "Failed r1(OK):${res1}" +fi + +_app_stop +} + +test_04(){ +# Run an app without JMX enabled +# start JMX by jcmd on one port, specify rmi port explicitly + +_echo "**** Test four ****" +_app_start + +_jcmd ManagementAgent.start jmxremote.port=$1 jmxremote.rmi.port=$2 jmxremote.authenticate=false jmxremote.ssl=false + +# First agent should connect +res1=`testme $1 $2` + +if [ "${res1}" = "OK_CONN" ] +then + _echo "Passed $1 $2" +else + _echo "Failed r1(NO):${res1}" + _app_stop "Failed" +fi + +_app_stop +} + +test_05(){ +# Run an app without JMX enabled, it will enable local server +# but should leave remote server disabled + +_echo "**** Test five ****" +_app_start + +_jcmd ManagementAgent.start jmxremote=1 + +# First agent should connect +res1=`testme $1` + +if [ "${res1}" = "NO_CONN" ] +then + _echo "Passed $1 $2" +else + _echo "Failed r1(OK):${res1}" + _app_stop "Failed" +fi + +_app_stop +} + +test_06(){ +# Run an app without JMX enabled +# start JMX by jcmd on one port, specify rmi port explicitly +# attempt to start it again +# 1) with the same port +# 2) with other port +# 3) attempt to stop it twice +# Check for valid messages in the output + +_echo "**** Test six ****" +_app_start + +_jcmd ManagementAgent.start jmxremote.port=$1 jmxremote.authenticate=false jmxremote.ssl=false + +# First agent should connect +res1=`testme $1 $2` + +if [ "${res1}" = "OK_CONN" ] +then + _echo "Passed $1 $2" +else + _echo "Failed r1(NO):${res1}" + _app_stop "Failed" +fi + +_jcmd ManagementAgent.start jmxremote.port=$1 jmxremote.authenticate=false jmxremote.ssl=false + +_jcmd ManagementAgent.start jmxremote.port=$2 jmxremote.authenticate=false jmxremote.ssl=false + +_jcmd ManagementAgent.stop + +_jcmd ManagementAgent.stop + +_jcmd ManagementAgent.start jmxremote.port=22 jmxremote.rmi.port=$2 jmxremote.authenticate=false jmxremote.ssl=false + +_app_stop +} + +test_07(){ +# Run an app without JMX enabled, but with some properties set +# in command line. +# make sure these properties overriden corectly + +_echo "**** Test seven ****" + +_app_start -Dcom.sun.management.jmxremote.authenticate=false \ + -Dcom.sun.management.jmxremote.ssl=true + +res1=`testme $1` + +_jcmd ManagementAgent.start jmxremote.port=$2 jmxremote.authenticate=false jmxremote.ssl=false + +res2=`testme $2` + + +if [ "${res1}" = "NO_CONN" -a "${res2}" = "OK_CONN" ] +then + echo "Passed" +else + _echo "Failed r1(NO):${res1} r2(OK):${res2}" + _app_stop "Failed" +fi + +_app_stop +} + +test_08(){ +# Run an app with JMX enabled and with some properties set +# in command line. +# stop JMX agent and then start it again with different property values +# make sure these properties overriden corectly + +_echo "**** Test eight ****" + +_app_start -Dcom.sun.management.jmxremote.port=$1 \ + -Dcom.sun.management.jmxremote.authenticate=false \ + -Dcom.sun.management.jmxremote.ssl=true + +res1=`testme $1` + +_jcmd ManagementAgent.stop + +res2=`testme $1` + +_jcmd ManagementAgent.start jmxremote.port=$2 jmxremote.authenticate=false jmxremote.ssl=false + +res3=`testme $2` + + +if [ "${res1}" = "NO_CONN" -a "${res2}" = "NO_CONN" -a "${res3}" = "OK_CONN" ] +then + _echo "Passed" +else + _echo "Failed r1(NO):${res1} r2(NO):${res2} r3(OK):${res3}" + _app_stop "Failed" +fi + +_app_stop +} + +test_09(){ +# Run an app with JMX enabled and with some properties set +# in command line. +# stop JMX agent and then start it again with different property values +# specifing some property in management config file and some of them +# in command line +# make sure these properties overriden corectly + +_echo "**** Test nine ****" + +_app_start -Dcom.sun.management.config.file=${_testsrc}/management_cl.properties \ + -Dcom.sun.management.jmxremote.authenticate=false + +res1=`testme $1` + +_jcmd ManagementAgent.stop + +res2=`testme $1` + +_jcmd ManagementAgent.start config.file=${_testsrc}/management_jcmd.properties \ + jmxremote.authenticate=false jmxremote.port=$2 + +res3=`testme $2` + +if [ "${res1}" = "NO_CONN" -a "${res2}" = "NO_CONN" -a "${res3}" = "OK_CONN" ] +then + _echo "Passed" +else + _echo "Failed r1(NO):${res1} r2(NO):${res2} r3(OK):${res3}" + _app_stop "Failed" +fi + +_app_stop +} + +test_10(){ +# Run an app with JMX enabled and with some properties set +# in command line. +# stop JMX agent and then start it again with different property values +# stop JMX agent again and then start it without property value +# make sure these properties overriden corectly + +_echo "**** Test ten ****" + +_app_start -Dcom.sun.management.jmxremote.port=$1 \ + -Dcom.sun.management.jmxremote.authenticate=false \ + -Dcom.sun.management.jmxremote.ssl=true + +res1=`testme $1` + +_jcmd ManagementAgent.stop +_jcmd ManagementAgent.start jmxremote.ssl=false jmxremote.port=$1 + + +res2=`testme $1` + +_jcmd ManagementAgent.stop +_jcmd ManagementAgent.start jmxremote.port=$1 + +res3=`testme $1` + +if [ "${res1}" = "NO_CONN" -a "${res2}" = "OK_CONN" -a "${res3}" = "NO_CONN" ] +then + _echo "Passed" +else + _echo "Failed r1(NO):${res1} r2(OK):${res2} r3(NO):${res3}" + _app_stop "Failed" +fi + +_app_stop +} + +test_11(){ +# Run an app with JMX enabled +# stop remote agent +# make sure local agent is not affected + +_echo "**** Test eleven ****" + +_app_start -Dcom.sun.management.jmxremote.port=$2 \ + -Dcom.sun.management.jmxremote.authenticate=false \ + -Dcom.sun.management.jmxremote.ssl=false + +res1=`testme $2` + +_jcmd ManagementAgent.stop + +pid=`${TESTJAVA}/bin/jps | sed -n "/JMXStartStopDoSomething/s/ .*//p"` +res2=`testme local ${pid}` + +if [ "${res1}" = "OK_CONN" -a "${res2}" = "OK_CONN" ] +then + _echo "Passed" +else + _echo "Failed r1(OK):${res1} r2(OK):${res2}" + _app_stop "Failed" +fi + +_app_stop +} + +test_12(){ +# Run an app with JMX disabled +# start local agent only + +_echo "**** Test twelve ****" + +_app_start + +res1=`testme $1` + +_jcmd ManagementAgent.start_local + +pid=`_get_pid` +if [ "x${pid}" = "x" ] +then + res2="NO_CONN" +else + res2=`testme local ${pid}` +fi + +if [ "${res1}" = "NO_CONN" -a "${res2}" = "OK_CONN" ] +then + _echo "Passed" +else + _echo "Failed r1(NO):${res1} r2(OK):${res2}" + _app_stop "Failed" +fi + +_app_stop +} + +test_13(){ +# Run an app with -javaagent make sure it works as expected - system properties are ignored + +_echo "**** Test 13 ****" + +AGENT="${TESTJAVA}/jre/lib/management-agent.jar" +if [ ! -f ${AGENT} ] + then + AGENT="${TESTJAVA}/lib/management-agent.jar" +fi + +_app_start -javaagent:${AGENT}=com.sun.management.jmxremote.port=$1,com.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false + +res1=`testme $1` + +if [ "${res1}" = "NO_CONN" ] +then + _echo "Passed" +else + _echo "Failed r1(NO):${res1}" + _app_stop "Failed" +fi + +_app_stop +} + + +#============== Server tests ======================= + +server_test_01(){ + + _echo "**** Server test one ****" + + _app_start -Dcom.sun.management.jmxremote.port=$1 \ + -Dcom.sun.management.jmxremote.rmi.port=$2 \ + -Dcom.sun.management.jmxremote.authenticate=false \ + -Dcom.sun.management.jmxremote.ssl=false + +} + + +# ============= MAIN ======================================= + +if [ "x${TESTJAVA}" = "x" ] +then + echo "TESTJAVA env have to be set" + exit +fi + +if [ ! -x "${TESTJAVA}/bin/jcmd" ] +then + echo "${TESTJAVA}/bin/jcmd" + echo "Doesn't exist or not an executable" + + if [ "${_verbose}" != "yes" ] + then + exit + fi +fi + + +#------------------------------------------------------------------------------ +# reading parameters + +for parm in "$@" +do + case $parm in + --verbose) _verbose=yes ;; + --server) _server=yes ;; + --jtreg) _jtreg=yes ;; + --no-compile) _compile=no ;; + --testsuite=*) _testsuite=`_echo $parm | sed "s,^--.*=\(.*\),\1,"` ;; + --port-one=*) _port_one=`_echo $parm | sed "s,^--.*=\(.*\),\1,"` ;; + --port-two=*) _port_two=`_echo $parm | sed "s,^--.*=\(.*\),\1,"` ;; + *) + echo "Undefined parameter $parm. Try --help for help" + exit + ;; + esac +done + +if [ ${_compile} = "yes" ] +then + _compile +fi + +if [ ${_jtreg} = "yes" ] +then + _testclasses=${TESTCLASSES} + _testsrc=${TESTSRC} + _logname="JMXStartStopTest_output.txt" +fi + +rm -f ${_logname} + +# Start server mode tests +# All of them require manual cleanup +if [ "x${_server}" = "xyes" ] +then + + server_test_01 ${_port_one} ${_port_two} + +else + + # Local mode tests + for i in `echo ${_testsuite} | sed -e "s/,/ /g"` + do + test_${i} ${_port_one} ${_port_two} + done + +fi + diff --git a/jdk/test/sun/management/jmxremote/startstop/REMOTE_TESTING.txt b/jdk/test/sun/management/jmxremote/startstop/REMOTE_TESTING.txt new file mode 100644 index 00000000000..03e8f8ba973 --- /dev/null +++ b/jdk/test/sun/management/jmxremote/startstop/REMOTE_TESTING.txt @@ -0,0 +1,11 @@ +1. Setup two hosts +2. Make sure tcp connection between them works +3. run tcpdump -i host and 'tcp[13] & 2!=0' + on host 1 +4. run JMXStartStopTest.sh --server on host2 +5. run jconsole on host1 +6. connect jconsole to host2:50234 + Make sure jconsole works + Make sure only host2.50234 and host2.50235 appears in tcpdump output. + + diff --git a/jdk/test/sun/management/jmxremote/startstop/management_cl.properties b/jdk/test/sun/management/jmxremote/startstop/management_cl.properties new file mode 100644 index 00000000000..f2bf53d6027 --- /dev/null +++ b/jdk/test/sun/management/jmxremote/startstop/management_cl.properties @@ -0,0 +1,2 @@ +com.sun.management.jmxremote.ssl=true +com.sun.management.internal.read_from_config_file_cl=true diff --git a/jdk/test/sun/management/jmxremote/startstop/management_jcmd.properties b/jdk/test/sun/management/jmxremote/startstop/management_jcmd.properties new file mode 100644 index 00000000000..b603818c577 --- /dev/null +++ b/jdk/test/sun/management/jmxremote/startstop/management_jcmd.properties @@ -0,0 +1,3 @@ +com.sun.management.jmxremote.ssl=false +jmxremote.authenticate=true +com.sun.management.internal.read_from_config_file_jcmd=true From 48ca85ec464ae5db993b59cbfc54796a46eaa550 Mon Sep 17 00:00:00 2001 From: Sean Mullan Date: Mon, 27 Feb 2012 11:44:50 -0500 Subject: [PATCH 19/43] 7147830: NullPointerException in java.security.Policy.implies() when the ProtectionDomain has a null code sou Reviewed-by: vinnie --- .../sun/security/provider/PolicyFile.java | 5 ++- .../provider/PolicyFile/NullCodeSource.java | 44 +++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 jdk/test/sun/security/provider/PolicyFile/NullCodeSource.java diff --git a/jdk/src/share/classes/sun/security/provider/PolicyFile.java b/jdk/src/share/classes/sun/security/provider/PolicyFile.java index c97ad1909aa..70bb8b9122b 100644 --- a/jdk/src/share/classes/sun/security/provider/PolicyFile.java +++ b/jdk/src/share/classes/sun/security/provider/PolicyFile.java @@ -1246,7 +1246,10 @@ public class PolicyFile extends java.security.Policy { * @return the set of permissions according to the policy. */ private PermissionCollection getPermissions(Permissions perms, - final CodeSource cs) { + final CodeSource cs) { + + if (cs == null) + return perms; CodeSource canonCodeSource = AccessController.doPrivileged( new java.security.PrivilegedAction(){ diff --git a/jdk/test/sun/security/provider/PolicyFile/NullCodeSource.java b/jdk/test/sun/security/provider/PolicyFile/NullCodeSource.java new file mode 100644 index 00000000000..42ebcc4bab8 --- /dev/null +++ b/jdk/test/sun/security/provider/PolicyFile/NullCodeSource.java @@ -0,0 +1,44 @@ +/* + * 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. + * + * 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. + */ + +/* + * @test + * @bug 7147830 + * @summary PolicyFile.getPermissions(CodeSource) should return + * empty permissions when passed in null code source + */ + +import java.security.CodeSource; +import java.security.PermissionCollection; +import java.security.Policy; + +public class NullCodeSource { + public static void main(String[] args) throws Exception { + Policy policy = Policy.getPolicy(); + PermissionCollection perms = policy.getPermissions((CodeSource)null); + if (perms.elements().hasMoreElements()) { + System.err.println(perms); + throw new Exception("PermissionCollection is not empty"); + } + } +} From 2f6d883fcb390e4ac304040fb36ca827f0294fd0 Mon Sep 17 00:00:00 2001 From: Mike Duigou Date: Mon, 27 Feb 2012 18:09:47 -0800 Subject: [PATCH 20/43] 7143162: Allow disable building of jdk demos and samples Reviewed-by: ohair --- make/sanity-rules.gmk | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/make/sanity-rules.gmk b/make/sanity-rules.gmk index fece2a9c638..544dba10ffd 100644 --- a/make/sanity-rules.gmk +++ b/make/sanity-rules.gmk @@ -38,7 +38,7 @@ ifeq ($(BUILD_DEPLOY), true) endif ifeq ($(BUILD_JDK), true) - sanity:: jdk-sanity + sanity:: jdk-sanity endif # Only need these sanity rules when not doing a debug build @@ -64,7 +64,7 @@ $(ERROR_FILE) $(WARNING_FILE) $(MESSAGE_FILE): purge-sanity: $(ERROR_FILE) $(WARNING_FILE) $(MESSAGE_FILE) -@$(RM) $(ERROR_FILE) $(WARNING_FILE) $(MESSAGE_FILE) -pre-sanity: purge-sanity +pre-sanity: purge-sanity # this should be the last rule in any target's sanity rule. post-sanity post-sanity-hotspot post-sanity-jdk post-sanity-install post-sanity-deploy: @@ -132,7 +132,7 @@ endif " $* defined. Please unset it and restart your build. \n" \ "" >> $(ERROR_FILE) -# Check the environment variables +# Check the environment variables environment: $(DO_NOT_SET_LIST:%=%.do_not_set) ifeq ($(LANGTOOLS_SRC_AVAILABLE), true) ifneq ($(BUILD_LANGTOOLS), true) @@ -205,7 +205,15 @@ ifeq ($(SPONSORS_SRC_AVAILABLE), true) endif endif ifeq ($(GENERATE_DOCS),false) - @$(ECHO) "WARNING: This build does not include running javadoc.\n" \ + @$(ECHO) "WARNING: This build does not include generating javadoc.\n" \ + "" >> $(WARNING_FILE) +endif +ifdef NO_DEMOS + @$(ECHO) "WARNING: This build and any install images will not include demos.\n" \ + "" >> $(WARNING_FILE) +endif +ifdef NO_SAMPLES + @$(ECHO) "WARNING: This build and any install images will not include samples.\n" \ "" >> $(WARNING_FILE) endif ifdef NO_IMAGES @@ -231,7 +239,7 @@ ifneq ($(PLATFORM), windows) HOSTNAME := $(shell hostname) endif endif -settings:: +settings:: @$(ECHO) "Build Machine Information:" >> $(MESSAGE_FILE) ifeq ($(PLATFORM), windows) @$(ECHO) " build machine = $(COMPUTERNAME)" >> $(MESSAGE_FILE) From 0193199d573771f26264a0f381f1e9fd0d0f8459 Mon Sep 17 00:00:00 2001 From: Mike Duigou Date: Mon, 27 Feb 2012 18:10:03 -0800 Subject: [PATCH 21/43] 7143162: Allow disable building of jdk demos and samples Reviewed-by: ohair --- jdk/make/Makefile | 15 ++++++++++++--- jdk/make/common/Release.gmk | 9 ++++++--- jdk/make/common/shared/Sanity-Settings.gmk | 3 ++- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/jdk/make/Makefile b/jdk/make/Makefile index d6a1d319a6a..fd39aa48853 100644 --- a/jdk/make/Makefile +++ b/jdk/make/Makefile @@ -197,7 +197,7 @@ examples_help: # # 'all' target intro # -all:: +all:: @$(ECHO) $(PLATFORM) $(ARCH) $(RELEASE) build started: $(shell $(DATE) '+%y-%m-%d %H:%M') # Just in case anyone uses this old name, same as 'build' @@ -234,7 +234,17 @@ all build:: sanity-all post-sanity-all SUBDIRS = tools java javax sun com SUBDIRS_tools = launchers -SUBDIRS_misc = org sunw jpda mkdemo mksample +SUBDIRS_misc = org sunw jpda + +# demos +ifndef NO_DEMOS + SUBDIRS_misc += mkdemo +endif + +# samples +ifndef NO_SAMPLES + SUBDIRS_misc += mksample +endif # Alternate classes implementation ifndef OPENJDK @@ -383,4 +393,3 @@ include jprt.gmk .PHONY: all build clean clobber optimized debug fastdebug create_links \ import import_product import_fastdebug import_debug \ test test_run test_start test_clean test_summary - diff --git a/jdk/make/common/Release.gmk b/jdk/make/common/Release.gmk index cd042ff0191..be0a450af5c 100644 --- a/jdk/make/common/Release.gmk +++ b/jdk/make/common/Release.gmk @@ -234,7 +234,7 @@ images:: sanity-images post-sanity-images \ $(INITIAL_IMAGE_JRE) $(INITIAL_IMAGE_JDK) \ trim-image-jre trim-image-jdk \ identify-image-jre identify-image-jdk \ - process-image-jre process-image-jdk sec-files sec-files-win jgss-files + process-image-jre process-image-jdk sec-files sec-files-win jgss-files # Don't use these image-jre:: initial-image-jre trim-image-jre identify-image-jre process-image-jre @@ -496,7 +496,7 @@ $(JDK_IMAGE_DIR)/demo/DEMOS_LICENSE: $(SHARE_JDK_DOC_SRC)/DEMOS_LICENSE $(JDK_IMAGE_DIR)/sample/SAMPLES_LICENSE: $(SHARE_JDK_DOC_SRC)/SAMPLES_LICENSE $(process-doc-file) -# JRE files +# JRE files $(JRE_IMAGE_DIR)/%: $(SHARE_JRE_DOC_SRC)/% $(process-doc-file) ifeq ($(PLATFORM), windows) @@ -1095,8 +1095,12 @@ initial-image-jdk:: initial-image-jdk-setup \ @# @# demo, include @# +ifndef NO_DEMOS $(CP) -r -f $(DEMODIR) $(JDK_IMAGE_DIR) +endif +ifndef NO_SAMPLES $(CP) -r -f $(SAMPLEDIR) $(JDK_IMAGE_DIR) +endif $(CP) -r $(INCLUDEDIR) $(JDK_IMAGE_DIR) @# @# Swing BeanInfo generation @@ -1359,4 +1363,3 @@ images images-clobber:: # Force rule FRC: - diff --git a/jdk/make/common/shared/Sanity-Settings.gmk b/jdk/make/common/shared/Sanity-Settings.gmk index ecc39c1a724..e571b068f82 100644 --- a/jdk/make/common/shared/Sanity-Settings.gmk +++ b/jdk/make/common/shared/Sanity-Settings.gmk @@ -134,6 +134,8 @@ ALL_SETTINGS+=$(call addOptionalSetting,USE_HOTSPOT_INTERPRETER_MODE) ALL_SETTINGS+=$(call addOptionalSetting,PEDANTIC) ALL_SETTINGS+=$(call addOptionalSetting,DEV_ONLY) ALL_SETTINGS+=$(call addOptionalSetting,NO_DOCS) +ALL_SETTINGS+=$(call addOptionalSetting,NO_DEMOS) +ALL_SETTINGS+=$(call addOptionalSetting,NO_SAMPLES) ALL_SETTINGS+=$(call addOptionalSetting,NO_IMAGES) ALL_SETTINGS+=$(call addOptionalSetting,TOOLS_ONLY) ALL_SETTINGS+=$(call addOptionalSetting,INSANE) @@ -263,4 +265,3 @@ ifdef OPENJDK ALL_SETTINGS+=$(call addAltSetting,PREVIOUS_JRE_FILE) ALL_SETTINGS+=$(call addAltSetting,PREVIOUS_RELEASE_IMAGE) endif - From 825a304b384157ca030442947ec409e4f3168921 Mon Sep 17 00:00:00 2001 From: Tom Rodriguez Date: Tue, 28 Feb 2012 10:04:01 -0800 Subject: [PATCH 22/43] 7145024: Crashes in ucrypto related to C2 Reviewed-by: kvn --- .../src/cpu/x86/vm/sharedRuntime_x86_64.cpp | 248 +++++++++++++++--- 1 file changed, 210 insertions(+), 38 deletions(-) diff --git a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp index 6c2a565453d..f918380eda7 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,8 @@ 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"); + slot += VMRegImpl::slots_per_word; if (map != NULL) { __ movq(Address(rsp, offset), in_regs[i].first()->as_Register()); if (in_sig_bt[i] == T_ARRAY) { @@ -1214,9 +1211,9 @@ static void save_or_restore_arguments(MacroAssembler* masm, // 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. From ff47163220653cff499a6c7b615b21f5104522bb Mon Sep 17 00:00:00 2001 From: Roland Westrelin Date: Tue, 28 Feb 2012 09:13:58 +0100 Subject: [PATCH 23/43] 6910461: Register allocator may insert spill code at wrong insertion index When resolving exception edges after register allocation, the C1 register allocator may insert spill code at the wrong insertion position. Reviewed-by: kvn, never --- hotspot/src/share/vm/c1/c1_LinearScan.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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(); } } From 14732a0d27503a38b7d3b8a0dfebb278a7c3a4d4 Mon Sep 17 00:00:00 2001 From: Dmitry Samersoff Date: Tue, 28 Feb 2012 17:00:28 +0400 Subject: [PATCH 24/43] 7149181: sun/management/jmxremote/startstop/JMXStartStopTest.sh failing on all platforms Disable test until JDK and hotspot changes meet each other. Reviewed-by: alanb, acorn --- jdk/test/ProblemList.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/jdk/test/ProblemList.txt b/jdk/test/ProblemList.txt index 121307a3c50..4b49cebbb25 100644 --- a/jdk/test/ProblemList.txt +++ b/jdk/test/ProblemList.txt @@ -144,6 +144,8 @@ javax/management/loading/LibraryLoader/LibraryLoaderTest.java windows-all # 7144846 javax/management/remote/mandatory/connection/ReconnectTest.java generic-all +# 7149181 +sun/management/jmxremote/startstop/JMXStartStopTest.sh generic-all ############################################################################ @@ -346,4 +348,3 @@ java/util/concurrent/locks/ReentrantLock/CancelledLockLoops.java generic-all java/util/TimeZone/TimeZoneDatePermissionCheck.sh solaris-all ############################################################################ - From 5707f715aa19cff2e06cde4bcf4f104d021dc58a Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Tue, 28 Feb 2012 10:25:53 -0800 Subject: [PATCH 25/43] 7144951: fix minor javadoc issues Reviewed-by: darcy --- .../classes/com/sun/source/tree/MemberReferenceTree.java | 4 ++-- .../src/share/classes/com/sun/tools/doclets/package.html | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/langtools/src/share/classes/com/sun/source/tree/MemberReferenceTree.java b/langtools/src/share/classes/com/sun/source/tree/MemberReferenceTree.java index 68efd16dc36..c17b96f6f0f 100644 --- a/langtools/src/share/classes/com/sun/source/tree/MemberReferenceTree.java +++ b/langtools/src/share/classes/com/sun/source/tree/MemberReferenceTree.java @@ -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 @@ -37,7 +37,7 @@ import javax.lang.model.element.Name; * expression # [ identifier | new ] * * - * @see JSR 292 + * @since 1.8 */ public interface MemberReferenceTree extends ExpressionTree { diff --git a/langtools/src/share/classes/com/sun/tools/doclets/package.html b/langtools/src/share/classes/com/sun/tools/doclets/package.html index edd87617f68..bc5abe1920d 100644 --- a/langtools/src/share/classes/com/sun/tools/doclets/package.html +++ b/langtools/src/share/classes/com/sun/tools/doclets/package.html @@ -1,5 +1,5 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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/jaxp.properties b/jaxp/jaxp.properties deleted file mode 100644 index 6693fd37bea..00000000000 --- a/jaxp/jaxp.properties +++ /dev/null @@ -1,37 +0,0 @@ -# -# Copyright (c) 2007, 2011, 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. -# - -drops.master.copy.base=${drops.dir} - -jaxp_src.bundle.name=jaxp145_01.zip -jaxp_src.bundle.md5.checksum=32394c780c8fb5e29775f623525993c0 -jaxp_src.master.bundle.dir=${drops.master.copy.base} -jaxp_src.master.bundle.url.base=http://download.java.net/jaxp/1.4.5 - -jaxp_tests.bundle.name=jaxp-1_4_5-unittests.zip -jaxp_tests.bundle.md5.checksum=fda9b9ad17c459880c077df6ecc7df80 -jaxp_tests.master.bundle.dir=${drops.master.copy.base} -jaxp_tests.master.bundle.url.base=http://download.java.net/jaxp/1.4.5 - 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