1 /*
   2  * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 #include <stdlib.h>
  26 #include <string.h>
  27 
  28 #include "jni.h"
  29 #include "jni_util.h"
  30 #include "jvm.h"
  31 
  32 #include "java_lang_reflect_Module.h"
  33 
  34 /*
  35  * Translates '.' to '/'.  Does no validation, assumption being that both
  36  * calling code in java.lang.reflect.Module and VM will do deeper validation.
  37  */
  38 JNIEXPORT void
  39 ToInternalForm(char *name)
  40 {
  41     char *p = name;
  42     while (*p != '\0') {
  43         if (*p == '.') {
  44             *p = '/';
  45         }
  46         p++;
  47     }
  48 }
  49 
  50 JNIEXPORT void JNICALL
  51 Java_java_lang_reflect_Module_defineModule0(JNIEnv *env, jclass cls, jobject module,
  52                                             jboolean is_open, jstring version,
  53                                             jstring location, jobjectArray packages)
  54 {
  55     char** pkgs = NULL;
  56     jsize idx;
  57     jsize pkgs_len = (*env)->GetArrayLength(env, packages);
  58 
  59     if (pkgs_len != 0 && (pkgs = calloc(pkgs_len, sizeof(char*))) == NULL) {
  60         JNU_ThrowOutOfMemoryError(env, NULL);
  61         return;
  62     } else {
  63         int valid = 1;
  64         for (idx = 0; idx < pkgs_len; idx++) {
  65             jstring pkg = (*env)->GetObjectArrayElement(env, packages, idx);
  66             jsize len = (*env)->GetStringUTFLength(env, pkg);
  67             jsize unicode_len = (*env)->GetStringLength(env, pkg);
  68 
  69             pkgs[idx] = malloc(len + 1);
  70             if (pkgs[idx] == NULL) {
  71                 JNU_ThrowOutOfMemoryError(env, NULL);
  72                 valid = 0;
  73                 break;
  74             }
  75 
  76             (*env)->GetStringUTFRegion(env, pkg, 0, unicode_len, pkgs[idx]);
  77             ToInternalForm(pkgs[idx]);
  78         }
  79 
  80         if (valid != 0) {
  81             JVM_DefineModule(env, module, is_open, version, location,
  82                     (const char* const*)pkgs, pkgs_len);
  83         }
  84     }
  85 
  86     for (idx = 0; idx < pkgs_len; idx++) {
  87         if (pkgs[idx] != NULL) {
  88             free(pkgs[idx]);
  89         }
  90     }
  91     free(pkgs);
  92 }
  93 
  94 JNIEXPORT void JNICALL
  95 Java_java_lang_reflect_Module_addReads0(JNIEnv *env, jclass cls, jobject from, jobject to)
  96 {
  97     JVM_AddReadsModule(env, from, to);
  98 }
  99 
 100 JNIEXPORT void JNICALL
 101 Java_java_lang_reflect_Module_addExports0(JNIEnv *env, jclass cls, jobject from,
 102                                           jstring pkg, jobject to)
 103 {
 104     jsize len;
 105     jsize unicode_len;
 106     char* pkg_name;
 107 
 108     if (pkg == NULL) {
 109         JNU_ThrowNullPointerException(env, "package is null");
 110         return;
 111     }
 112 
 113     len = (*env)->GetStringUTFLength(env, pkg);
 114     unicode_len = (*env)->GetStringLength(env, pkg);
 115     pkg_name = malloc(len + 1);
 116     if (pkg_name == NULL) {
 117         JNU_ThrowOutOfMemoryError(env, NULL);
 118     } else {
 119         (*env)->GetStringUTFRegion(env, pkg, 0, unicode_len, pkg_name);
 120         ToInternalForm(pkg_name);
 121         JVM_AddModuleExports(env, from, pkg_name, to);
 122         free(pkg_name);
 123     }
 124 }
 125 
 126 JNIEXPORT void JNICALL
 127 Java_java_lang_reflect_Module_addExportsToAll0(JNIEnv *env, jclass cls, jobject from,
 128                                                jstring pkg)
 129 {
 130     jsize len;
 131     jsize unicode_len;
 132     char* pkg_name;
 133 
 134     if (pkg == NULL) {
 135         JNU_ThrowNullPointerException(env, "package is null");
 136         return;
 137     }
 138 
 139     len = (*env)->GetStringUTFLength(env, pkg);
 140     unicode_len = (*env)->GetStringLength(env, pkg);
 141     pkg_name = malloc(len + 1);
 142     if (pkg_name == NULL) {
 143         JNU_ThrowOutOfMemoryError(env, NULL);
 144     } else {
 145         (*env)->GetStringUTFRegion(env, pkg, 0, unicode_len, pkg_name);
 146         ToInternalForm(pkg_name);
 147         JVM_AddModuleExportsToAll(env, from, pkg_name);
 148         free(pkg_name);
 149     }
 150 }
 151 
 152 JNIEXPORT void JNICALL
 153 Java_java_lang_reflect_Module_addExportsToAllUnnamed0(JNIEnv *env, jclass cls,
 154                                                       jobject from, jstring pkg)
 155 {
 156     jsize len;
 157     jsize unicode_len;
 158     char* pkg_name;
 159 
 160     if (pkg == NULL) {
 161         JNU_ThrowNullPointerException(env, "package is null");
 162         return;
 163     }
 164 
 165     len = (*env)->GetStringUTFLength(env, pkg);
 166     unicode_len = (*env)->GetStringLength(env, pkg);
 167     pkg_name = malloc(len + 1);
 168     if (pkg_name == NULL) {
 169         JNU_ThrowOutOfMemoryError(env, NULL);
 170     } else {
 171         (*env)->GetStringUTFRegion(env, pkg, 0, unicode_len, pkg_name);
 172         ToInternalForm(pkg_name);
 173         JVM_AddModuleExportsToAllUnnamed(env, from, pkg_name);
 174         free(pkg_name);
 175     }
 176 }
 177 
 178 JNIEXPORT void JNICALL
 179 Java_java_lang_reflect_Module_addPackage0(JNIEnv *env, jclass cls, jobject m, jstring pkg)
 180 {
 181     jsize len;
 182     jsize unicode_len;
 183     char* pkg_name;
 184 
 185     if (pkg == NULL) {
 186         JNU_ThrowNullPointerException(env, "package is null");
 187         return;
 188     }
 189 
 190     len = (*env)->GetStringUTFLength(env, pkg);
 191     unicode_len = (*env)->GetStringLength(env, pkg);
 192     pkg_name = malloc(len + 1);
 193     if (pkg_name == NULL) {
 194         JNU_ThrowOutOfMemoryError(env, NULL);
 195     } else {
 196         (*env)->GetStringUTFRegion(env, pkg, 0, unicode_len, pkg_name);
 197         ToInternalForm(pkg_name);
 198         JVM_AddModulePackage(env, m, pkg_name);
 199         free(pkg_name);
 200     }
 201 }