/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * The contents of this file are subject to the Netscape Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/NPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is mozilla.org code. * * The Initial Developer of the Original Code is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1998 Netscape Communications Corporation. All * Rights Reserved. * * Contributor(s): */ #include "java_lang_reflect_Constructor.h" #include "java_lang_Class.h" #include "JavaVM.h" #include "FieldOrMethod.h" #include "SysCallsRuntime.h" #include "StackWalker.h" #include // Make sure that the class that called this method can access this field. // Throw an IllegalAccessException if it can't. static inline void checkCallingClass(const Method &method) { Frame thisFrame; Method &callerMethod = thisFrame.getCallingJavaMethod(); if (callerMethod.getDeclaringClass() != method.getDeclaringClass()) { if ((method.getModifiers() & CR_METHOD_PRIVATE)) sysThrowNamedException("java/lang/IllegalAccessException"); else if ((method.getModifiers() & CR_METHOD_PROTECTED)) { if (!method.getDeclaringClass()->isAssignableFrom(*(const Type *) callerMethod.getDeclaringClass())) sysThrowNamedException("java/lang/IllegalAccessException"); } } } static void throwConstructorException(RuntimeError err) { // FIXME Need to check for illegalAccess, which we currently do not enforce // Also need to throw an InvocationTargetException switch (err.cause) { case RuntimeError::nullPointer: sysThrowNullPointerException(); break; case RuntimeError::illegalArgument: sysThrowNamedException("java/lang/IllegalArgumentException"); break; case RuntimeError::notInstantiable: sysThrowNamedException("java/lang/InstantiationException"); break; default: trespass("Unknown Runtime Error in throwConstructorException()"); } } extern "C" { /* XXX Routines returning strings will have to be redone once the VM supports * unicode strings directly */ static inline Constructor &toConstructor(Java_java_lang_reflect_Constructor *inConstr) { if (!inConstr) sysThrowNullPointerException(); return *(Constructor *) inConstr; } /* * Class : java/lang/reflect/Constructor * Method : equals * Signature : (Ljava/lang/Object;)Z */ NS_EXPORT NS_NATIVECALL(uint32 /* bool */) Netscape_Java_java_lang_reflect_Constructor_equals(Java_java_lang_reflect_Constructor *inConstr, Java_java_lang_Object *inObj) { Constructor &constructor = toConstructor(inConstr); JavaObject *obj = (JavaObject *) inObj; return obj && constructor.equals(*obj); } /* * Class : java/lang/reflect/Constructor * Method : getDeclaringClass * Signature : ()Ljava/lang/Class; */ NS_EXPORT NS_NATIVECALL(Java_java_lang_Class *) Netscape_Java_java_lang_reflect_Constructor_getDeclaringClass(Java_java_lang_reflect_Constructor *inConstr) { Constructor &constructor = toConstructor(inConstr); return ((Java_java_lang_Class *) constructor.getDeclaringClass()); } /* * Class : java/lang/reflect/Constructor * Method : getExceptionTypes * Signature : ()[Ljava/lang/Class; */ NS_EXPORT NS_NATIVECALL(ArrayOf_Java_java_lang_Class *) Netscape_Java_java_lang_reflect_Constructor_getExceptionTypes(Java_java_lang_reflect_Constructor *) { printf("Netscape_Java_java_lang_reflect_Constructor_getExceptionTypes() not implemented\n"); return 0; } /* * Class : java/lang/reflect/Constructor * Method : getModifiers * Signature : ()I */ NS_EXPORT NS_NATIVECALL(int32) Netscape_Java_java_lang_reflect_Constructor_getModifiers(Java_java_lang_reflect_Constructor *inConstr) { Constructor &constructor = toConstructor(inConstr); return constructor.getModifiers(); } /* * Class : java/lang/reflect/Constructor * Method : getParameterTypes * Signature : ()[Ljava/lang/Class; */ NS_EXPORT NS_NATIVECALL(ArrayOf_Java_java_lang_Class *) Netscape_Java_java_lang_reflect_Constructor_getParameterTypes(Java_java_lang_reflect_Constructor *inConstr) { Constructor &constructor = toConstructor(inConstr); const Type **params; Int32 numParams; numParams = constructor.getParameterTypes(params); void *arr = sysNewObjectArray(&VM::getStandardClass(cClass), numParams-1); ArrayOf_Java_java_lang_Class *clazzArray = (ArrayOf_Java_java_lang_Class *) arr; // The first parameter is always ourselves for (Int32 i = 1; i < numParams; i++) clazzArray->elements[i-1] = (Java_java_lang_Class *)params[i]; return clazzArray; } /* * Class : java/lang/reflect/Constructor * Method : newInstance * Signature : ([Ljava/lang/Object;)Ljava/lang/Object; */ NS_EXPORT NS_NATIVECALL(Java_java_lang_Object *) Netscape_Java_java_lang_reflect_Constructor_newInstance(Java_java_lang_reflect_Constructor *inConstr, ArrayOf_Java_java_lang_Object *inParams) { Constructor &constructor = toConstructor(inConstr); checkCallingClass(constructor); JavaObject **params = (JavaObject **) inParams->elements; Int32 numParams = (inParams) ? inParams->length : 0; try { return (Java_java_lang_Object *) &constructor.newInstance(params, numParams); } catch (RuntimeError err) { throwConstructorException(err); } } /* * Class : java/lang/reflect/Constructor * Method : toString * Signature : ()Ljava/lang/String; */ NS_EXPORT NS_NATIVECALL(Java_java_lang_String *) Netscape_Java_java_lang_reflect_Constructor_toString(Java_java_lang_reflect_Constructor *inConstr) { Constructor &constructor = toConstructor(inConstr); const char *str = constructor.toString(); return ((Java_java_lang_String *) &VM::intern(str)); } }