jdk-24/test/jdk/java/foreign/libVarArgs.c
Jorn Vernee ac2f8e5af8 8327994: Update code gen in CallGeneratorHelper
Reviewed-by: mcimadamore
2024-03-21 12:34:38 +00:00

238 lines
6.3 KiB
C

/*
* Copyright (c) 2020, 2024, 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.
*
*/
#include <stdarg.h>
#include <stdlib.h>
#include "shared.h"
struct S_FFFF { float p0; float p1; float p2; float p3; };
typedef void (*writeback_t)(int,void*);
typedef struct {
writeback_t writeback;
int* argids;
} call_info;
#define CASE(num, type) case num: { \
type x = va_arg(a_list, type); \
writeback(i, &x); \
} break;
enum NativeType {
T_INT,
T_DOUBLE,
T_POINTER,
T_S_I,
T_S_F,
T_S_D,
T_S_P,
T_S_II,
T_S_IF,
T_S_ID,
T_S_IP,
T_S_FI,
T_S_FF,
T_S_FD,
T_S_FP,
T_S_DI,
T_S_DF,
T_S_DD,
T_S_DP,
T_S_PI,
T_S_PF,
T_S_PD,
T_S_PP,
T_S_III,
T_S_IIF,
T_S_IID,
T_S_IIP,
T_S_IFI,
T_S_IFF,
T_S_IFD,
T_S_IFP,
T_S_IDI,
T_S_IDF,
T_S_IDD,
T_S_IDP,
T_S_IPI,
T_S_IPF,
T_S_IPD,
T_S_IPP,
T_S_FII,
T_S_FIF,
T_S_FID,
T_S_FIP,
T_S_FFI,
T_S_FFF,
T_S_FFD,
T_S_FFP,
T_S_FDI,
T_S_FDF,
T_S_FDD,
T_S_FDP,
T_S_FPI,
T_S_FPF,
T_S_FPD,
T_S_FPP,
T_S_DII,
T_S_DIF,
T_S_DID,
T_S_DIP,
T_S_DFI,
T_S_DFF,
T_S_DFD,
T_S_DFP,
T_S_DDI,
T_S_DDF,
T_S_DDD,
T_S_DDP,
T_S_DPI,
T_S_DPF,
T_S_DPD,
T_S_DPP,
T_S_PII,
T_S_PIF,
T_S_PID,
T_S_PIP,
T_S_PFI,
T_S_PFF,
T_S_PFD,
T_S_PFP,
T_S_PDI,
T_S_PDF,
T_S_PDD,
T_S_PDP,
T_S_PPI,
T_S_PPF,
T_S_PPD,
T_S_PPP,
T_S_FFFF,
};
// need to pass `num` separately as last argument preceding varargs according to spec (and for MSVC)
EXPORT void varargs(call_info* info, int num, ...) {
va_list a_list;
va_start(a_list, num);
writeback_t writeback = info->writeback;
for (int i = 0; i < num; i++) {
int id = info->argids[i];
switch (id) {
CASE(T_INT, int)
CASE(T_DOUBLE, double)
CASE(T_POINTER, void*)
CASE(T_S_I, struct S_I)
CASE(T_S_F, struct S_F)
CASE(T_S_D, struct S_D)
CASE(T_S_P, struct S_P)
CASE(T_S_II, struct S_II)
CASE(T_S_IF, struct S_IF)
CASE(T_S_ID, struct S_ID)
CASE(T_S_IP, struct S_IP)
CASE(T_S_FI, struct S_FI)
CASE(T_S_FF, struct S_FF)
CASE(T_S_FD, struct S_FD)
CASE(T_S_FP, struct S_FP)
CASE(T_S_DI, struct S_DI)
CASE(T_S_DF, struct S_DF)
CASE(T_S_DD, struct S_DD)
CASE(T_S_DP, struct S_DP)
CASE(T_S_PI, struct S_PI)
CASE(T_S_PF, struct S_PF)
CASE(T_S_PD, struct S_PD)
CASE(T_S_PP, struct S_PP)
CASE(T_S_III, struct S_III)
CASE(T_S_IIF, struct S_IIF)
CASE(T_S_IID, struct S_IID)
CASE(T_S_IIP, struct S_IIP)
CASE(T_S_IFI, struct S_IFI)
CASE(T_S_IFF, struct S_IFF)
CASE(T_S_IFD, struct S_IFD)
CASE(T_S_IFP, struct S_IFP)
CASE(T_S_IDI, struct S_IDI)
CASE(T_S_IDF, struct S_IDF)
CASE(T_S_IDD, struct S_IDD)
CASE(T_S_IDP, struct S_IDP)
CASE(T_S_IPI, struct S_IPI)
CASE(T_S_IPF, struct S_IPF)
CASE(T_S_IPD, struct S_IPD)
CASE(T_S_IPP, struct S_IPP)
CASE(T_S_FII, struct S_FII)
CASE(T_S_FIF, struct S_FIF)
CASE(T_S_FID, struct S_FID)
CASE(T_S_FIP, struct S_FIP)
CASE(T_S_FFI, struct S_FFI)
CASE(T_S_FFF, struct S_FFF)
CASE(T_S_FFD, struct S_FFD)
CASE(T_S_FFP, struct S_FFP)
CASE(T_S_FDI, struct S_FDI)
CASE(T_S_FDF, struct S_FDF)
CASE(T_S_FDD, struct S_FDD)
CASE(T_S_FDP, struct S_FDP)
CASE(T_S_FPI, struct S_FPI)
CASE(T_S_FPF, struct S_FPF)
CASE(T_S_FPD, struct S_FPD)
CASE(T_S_FPP, struct S_FPP)
CASE(T_S_DII, struct S_DII)
CASE(T_S_DIF, struct S_DIF)
CASE(T_S_DID, struct S_DID)
CASE(T_S_DIP, struct S_DIP)
CASE(T_S_DFI, struct S_DFI)
CASE(T_S_DFF, struct S_DFF)
CASE(T_S_DFD, struct S_DFD)
CASE(T_S_DFP, struct S_DFP)
CASE(T_S_DDI, struct S_DDI)
CASE(T_S_DDF, struct S_DDF)
CASE(T_S_DDD, struct S_DDD)
CASE(T_S_DDP, struct S_DDP)
CASE(T_S_DPI, struct S_DPI)
CASE(T_S_DPF, struct S_DPF)
CASE(T_S_DPD, struct S_DPD)
CASE(T_S_DPP, struct S_DPP)
CASE(T_S_PII, struct S_PII)
CASE(T_S_PIF, struct S_PIF)
CASE(T_S_PID, struct S_PID)
CASE(T_S_PIP, struct S_PIP)
CASE(T_S_PFI, struct S_PFI)
CASE(T_S_PFF, struct S_PFF)
CASE(T_S_PFD, struct S_PFD)
CASE(T_S_PFP, struct S_PFP)
CASE(T_S_PDI, struct S_PDI)
CASE(T_S_PDF, struct S_PDF)
CASE(T_S_PDD, struct S_PDD)
CASE(T_S_PDP, struct S_PDP)
CASE(T_S_PPI, struct S_PPI)
CASE(T_S_PPF, struct S_PPF)
CASE(T_S_PPD, struct S_PPD)
CASE(T_S_PPP, struct S_PPP)
CASE(T_S_FFFF, struct S_FFFF)
default: exit(-1); // invalid id
}
}
va_end(a_list);
}