[K/N][Tests] Move filecheck and cinterop tests to /native/
^KT-61259
This commit is contained in:
committed by
Space Team
parent
05cbe66ee0
commit
bf0150108d
@@ -0,0 +1,34 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// MODULE: cinterop
|
||||
// FILE: carrayPointers.def
|
||||
---
|
||||
int (*arrayPointer)[1];
|
||||
|
||||
int globalArray[3] = {1, 2, 3};
|
||||
|
||||
struct StructWithArrayPtr {
|
||||
int (*arrayPointer)[1];
|
||||
};
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
import carrayPointers.*
|
||||
import kotlin.test.*
|
||||
import kotlinx.cinterop.*
|
||||
|
||||
fun box(): String {
|
||||
arrayPointer = globalArray
|
||||
assertEquals(globalArray[0], arrayPointer!![0])
|
||||
arrayPointer!![0] = 15
|
||||
assertEquals(15, globalArray[0])
|
||||
|
||||
memScoped {
|
||||
val struct = alloc<StructWithArrayPtr>()
|
||||
struct.arrayPointer = globalArray
|
||||
assertEquals(globalArray[0], struct.arrayPointer!![0])
|
||||
}
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// FREE_CINTEROP_ARGS: -header auxiliaryCppSources.h
|
||||
|
||||
// MODULE: cinterop
|
||||
// FILE: auxiliaryCppSources.def
|
||||
# The def file is intentionally empty
|
||||
# `auxiliaryCppSources.h` is meant to be included via `-header` free arg of cinterop tool
|
||||
|
||||
// FILE: auxiliaryCppSources.h
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
const char* name();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
// FILE: auxiliaryCppSources.cpp
|
||||
#include <string>
|
||||
#include "auxiliaryCppSources.h"
|
||||
|
||||
static std::string _name = "OK";
|
||||
|
||||
extern "C" const char* name() {
|
||||
return _name.c_str();
|
||||
}
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
import auxiliaryCppSources.*
|
||||
import kotlin.test.*
|
||||
import kotlinx.cinterop.*
|
||||
|
||||
fun box(): String {
|
||||
return name()!!.toKString()
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2010-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// MODULE: cinterop
|
||||
// FILE: cstdlib.def
|
||||
headers = stdlib.h
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
import cstdlib.*
|
||||
import kotlinx.cinterop.*
|
||||
import kotlin.test.*
|
||||
|
||||
fun box(): String {
|
||||
assertEquals(257, atoi("257"))
|
||||
|
||||
val divResult = div(-5, 3)
|
||||
val (quot, rem) = divResult.useContents { Pair(quot, rem) }
|
||||
assertEquals(-1, quot)
|
||||
assertEquals(-2, rem)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2010-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// MODULE: cinterop
|
||||
// FILE: cstdlib.def
|
||||
headers = stdlib.h
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
import cstdlib.*
|
||||
import kotlinx.cinterop.*
|
||||
import kotlin.test.*
|
||||
|
||||
fun box(): String {
|
||||
val values = intArrayOf(14, 12, 9, 13, 8)
|
||||
val count = values.size
|
||||
|
||||
qsort(values.refTo(0), count.convert(), IntVar.size.convert(), staticCFunction { a, b ->
|
||||
val aValue = a!!.reinterpret<IntVar>()[0]
|
||||
val bValue = b!!.reinterpret<IntVar>()[0]
|
||||
|
||||
(aValue - bValue)
|
||||
})
|
||||
|
||||
assertEquals(8, values[0])
|
||||
assertEquals(9, values[1])
|
||||
assertEquals(12, values[2])
|
||||
assertEquals(13, values[3])
|
||||
assertEquals(14, values[4])
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// MODULE: cinterop
|
||||
// FILE: cstdlib.def
|
||||
headers = stdlib.h processor_count.h
|
||||
compilerOpts.mingw = -D ADD_WINDOWS_ENV_FUNCTIONS
|
||||
|
||||
---
|
||||
|
||||
#ifdef ADD_WINDOWS_ENV_FUNCTIONS
|
||||
static inline int setenv(const char *name, const char *value, int overwrite)
|
||||
{
|
||||
int errcode = 0;
|
||||
if (!overwrite) {
|
||||
size_t envsize = 0;
|
||||
errcode = getenv_s(&envsize, NULL, 0, name);
|
||||
if(errcode || envsize) return errcode;
|
||||
}
|
||||
return _putenv_s(name, value);
|
||||
}
|
||||
static inline int unsetenv(const char *name)
|
||||
{
|
||||
return _putenv_s(name, "");
|
||||
}
|
||||
#endif
|
||||
|
||||
// FILE: processor_count.h
|
||||
int availableProcessors();
|
||||
|
||||
// FILE: processor_count.cpp
|
||||
#include <thread>
|
||||
extern "C" {
|
||||
#include "processor_count.h"
|
||||
int availableProcessors () { return std::thread::hardware_concurrency(); }
|
||||
}
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class, kotlin.experimental.ExperimentalNativeApi::class)
|
||||
|
||||
import kotlin.native.*
|
||||
import kotlin.test.*
|
||||
import cstdlib.*
|
||||
import kotlinx.cinterop.*
|
||||
|
||||
|
||||
@OptIn(kotlin.ExperimentalStdlibApi::class)
|
||||
fun box(): String {
|
||||
val platformProcessors: Int = Platform.getAvailableProcessors()
|
||||
assertTrue(platformProcessors > 0)
|
||||
assertEquals(availableProcessors(), platformProcessors)
|
||||
|
||||
setenv("KOTLIN_NATIVE_AVAILABLE_PROCESSORS", "12345", 1)
|
||||
assertEquals(Platform.getAvailableProcessors(), 12345)
|
||||
setenv("KOTLIN_NATIVE_AVAILABLE_PROCESSORS", Long.MAX_VALUE.toString(), 1)
|
||||
assertFailsWith<IllegalStateException> { Platform.getAvailableProcessors() }
|
||||
setenv("KOTLIN_NATIVE_AVAILABLE_PROCESSORS", "-1", 1)
|
||||
assertFailsWith<IllegalStateException> { Platform.getAvailableProcessors() }
|
||||
setenv("KOTLIN_NATIVE_AVAILABLE_PROCESSORS", "0", 1)
|
||||
assertFailsWith<IllegalStateException> { Platform.getAvailableProcessors() }
|
||||
// windows doesn't support empty env variables
|
||||
if (Platform.osFamily != OsFamily.WINDOWS) {
|
||||
setenv("KOTLIN_NATIVE_AVAILABLE_PROCESSORS", "", 1)
|
||||
assertFailsWith<IllegalStateException> { Platform.getAvailableProcessors() }
|
||||
}
|
||||
setenv("KOTLIN_NATIVE_AVAILABLE_PROCESSORS", "123aaaa", 1)
|
||||
assertFailsWith<IllegalStateException> { Platform.getAvailableProcessors() }
|
||||
unsetenv("KOTLIN_NATIVE_AVAILABLE_PROCESSORS")
|
||||
assertEquals(Platform.getAvailableProcessors(), platformProcessors)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright 2010-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// MODULE: cinterop
|
||||
// FILE: cmacros.def
|
||||
excludedMacros = EXCLUDED
|
||||
---
|
||||
int* ptr_call() {
|
||||
return (int*) 1;
|
||||
}
|
||||
|
||||
int int_call() {
|
||||
return 42;
|
||||
}
|
||||
|
||||
void void_call() {}
|
||||
|
||||
int arg_call(int x) {
|
||||
return x;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
int value
|
||||
} struct_t;
|
||||
|
||||
struct_t getStruct() {
|
||||
return (struct_t){ 1 };
|
||||
}
|
||||
|
||||
int global_var = 5;
|
||||
|
||||
#define TOO_MANY_ERRORS x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x
|
||||
|
||||
#define LEFT_BRACE {
|
||||
|
||||
#define ZERO 0
|
||||
#define ONE 1
|
||||
|
||||
#define RIGHT_BRACE }
|
||||
|
||||
#define MAX_LONG 9223372036854775807
|
||||
#define FOO_STRING "foo"
|
||||
// This one should be ignored:
|
||||
#define WIDE_FOO_STRING L"foo"
|
||||
#define FOURTY_TWO 42
|
||||
#define SEVENTEEN ((long long) 17)
|
||||
#define ONE_POINT_ZERO 1.0
|
||||
#define ONE_POINT_FIVE 1.5f
|
||||
|
||||
#define LEFT_PAREN (
|
||||
|
||||
#define NULL_PTR ((void*)0)
|
||||
#define VOID_PTR ((void*)1)
|
||||
#define INT_PTR ((int*)1)
|
||||
#define PTR_SUM (INT_PTR + 1)
|
||||
#define PTR_SUM_EXPECTED (sizeof(int) + 1)
|
||||
|
||||
#define RIGHT_PAREN )
|
||||
|
||||
enum {
|
||||
INT_CALL = 1 // Should be replaced by macro below.
|
||||
};
|
||||
|
||||
#define PTR_CALL ptr_call()
|
||||
#define INT_CALL int_call()
|
||||
#define CALL_SUM (int_call() + int_call())
|
||||
#define GLOBAL_VAR (global_var)
|
||||
|
||||
// This one should be excluded:
|
||||
#define EXCLUDED 42
|
||||
|
||||
// These ones should be ignored:
|
||||
#define VOID_CALL (void_call())
|
||||
#define ARG_CALL(x) (arg_call(x))
|
||||
#define GET_STRUCT (getStruct())
|
||||
#define UNDECLARED (undeclared())
|
||||
|
||||
#define BAD1 bar
|
||||
#define BAD2 5;
|
||||
#define BAD3 { foo(); }
|
||||
|
||||
void increment(int* counter);
|
||||
#define increment(counter) { (*(counter))++; }
|
||||
|
||||
#define DEFAULT_DOUBLE_NAN __builtin_nan("")
|
||||
#define DEFAULT_FLOAT_NAN __builtin_nanf("")
|
||||
#define OTHER_DOUBLE_NAN __builtin_nan("0x123456789ab")
|
||||
#define OTHER_FLOAT_NAN __builtin_nanf("0x12345")
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
|
||||
@file:OptIn(kotlin.experimental.ExperimentalNativeApi::class, kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
import kotlin.test.*
|
||||
import cmacros.*
|
||||
import kotlinx.cinterop.*
|
||||
|
||||
fun box(): String {
|
||||
assertEquals("foo", FOO_STRING)
|
||||
assertEquals(0, ZERO)
|
||||
assertEquals(1, ONE)
|
||||
assertEquals(Long.MAX_VALUE, MAX_LONG)
|
||||
assertEquals(42, FOURTY_TWO)
|
||||
|
||||
val seventeen: Long = SEVENTEEN
|
||||
assertEquals(17L, seventeen)
|
||||
|
||||
val onePointFive: Float = ONE_POINT_FIVE
|
||||
val onePointZero: Double = ONE_POINT_ZERO
|
||||
|
||||
assertEquals(1.5f, onePointFive)
|
||||
assertEquals(1.0, onePointZero)
|
||||
|
||||
val nullPtr: COpaquePointer? = NULL_PTR
|
||||
val voidPtr: COpaquePointer? = VOID_PTR
|
||||
val intPtr: CPointer<IntVar>? = INT_PTR
|
||||
val ptrSum: CPointer<IntVar>? = PTR_SUM
|
||||
val ptrCall: CPointer<IntVar>? = PTR_CALL
|
||||
|
||||
assertEquals(null, nullPtr)
|
||||
assertEquals(1L, voidPtr.rawValue.toLong())
|
||||
assertEquals(1L, intPtr.rawValue.toLong())
|
||||
assertEquals(PTR_SUM_EXPECTED.toLong(), ptrSum.rawValue.toLong())
|
||||
assertEquals(1L, ptrCall.rawValue.toLong())
|
||||
|
||||
assertEquals(42, INT_CALL)
|
||||
assertEquals(84, CALL_SUM)
|
||||
assertEquals(5, GLOBAL_VAR)
|
||||
|
||||
memScoped {
|
||||
val counter = alloc<IntVar>()
|
||||
counter.value = 42
|
||||
increment(counter.ptr)
|
||||
assertEquals(43, counter.value)
|
||||
}
|
||||
|
||||
|
||||
val floatNanBase = Float.NaN.toRawBits()
|
||||
assertEquals(floatNanBase, 0x7fc00000)
|
||||
val doubleNanBase = Double.NaN.toRawBits()
|
||||
assertEquals(doubleNanBase, 0x7ff8000000000000L)
|
||||
assertEquals(floatNanBase, DEFAULT_FLOAT_NAN.toRawBits())
|
||||
assertEquals(doubleNanBase, DEFAULT_DOUBLE_NAN.toRawBits())
|
||||
assertEquals(floatNanBase, OTHER_FLOAT_NAN.toRawBits())
|
||||
assertEquals(doubleNanBase, OTHER_DOUBLE_NAN.toRawBits())
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// MODULE: cinterop
|
||||
// FILE: mangling.def
|
||||
---
|
||||
|
||||
// test mangling of special names
|
||||
|
||||
enum _Companion {Companion, Any};
|
||||
enum _Companion companion = Companion;
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
import kotlinx.cinterop.*
|
||||
import kotlin.test.*
|
||||
import mangling.*
|
||||
|
||||
fun box(): String {
|
||||
companion = _Companion.`Companion$`
|
||||
assertEquals(_Companion.`Companion$`, companion)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// MODULE: cinterop
|
||||
// FILE: mangling2.def
|
||||
---
|
||||
|
||||
// test mangling of special names
|
||||
|
||||
enum Companion {One, Two};
|
||||
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
import kotlinx.cinterop.*
|
||||
import kotlin.test.*
|
||||
import mangling2.*
|
||||
|
||||
fun box(): String {
|
||||
val mangled = `Companion$`.Two
|
||||
assertEquals(`Companion$`.Two, mangled)
|
||||
return "OK"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// MODULE: cinterop
|
||||
// FILE: mangling_keywords.def
|
||||
---
|
||||
#define as "as"
|
||||
#define class "class"
|
||||
#define dynamic "dynamic"
|
||||
#define false "false"
|
||||
#define fun "fun"
|
||||
#define in "in"
|
||||
#define interface "interface"
|
||||
#define is "is"
|
||||
#define null "null"
|
||||
#define object "object"
|
||||
#define package "package"
|
||||
#define super "super"
|
||||
#define this "this"
|
||||
#define throw "throw"
|
||||
#define true "true"
|
||||
#define try "try"
|
||||
#define typealias "typealias"
|
||||
#define val "val"
|
||||
#define var "var"
|
||||
#define when "when"
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
import kotlin.test.*
|
||||
import mangling_keywords.*
|
||||
|
||||
fun box(): String {
|
||||
// Check that all Kotlin keywords are imported and mangled.
|
||||
assertEquals("as", `as`)
|
||||
assertEquals("class", `class`)
|
||||
assertEquals("dynamic", `dynamic`)
|
||||
assertEquals("false", `false`)
|
||||
assertEquals("fun", `fun`)
|
||||
assertEquals("in", `in`)
|
||||
assertEquals("interface", `interface`)
|
||||
assertEquals("is", `is`)
|
||||
assertEquals("null", `null`)
|
||||
assertEquals("object", `object`)
|
||||
assertEquals("package", `package`)
|
||||
assertEquals("super", `super`)
|
||||
assertEquals("this", `this`)
|
||||
assertEquals("throw", `throw`)
|
||||
assertEquals("true", `true`)
|
||||
assertEquals("try", `try`)
|
||||
assertEquals("typealias", `typealias`)
|
||||
assertEquals("val", `val`)
|
||||
assertEquals("var", `var`)
|
||||
assertEquals("when", `when`)
|
||||
return "OK"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// MODULE: cinterop
|
||||
// FILE: mangling_keywords2.def
|
||||
---
|
||||
enum KotlinKeywordsEnum {
|
||||
as,
|
||||
class,
|
||||
dynamic,
|
||||
false,
|
||||
fun,
|
||||
in,
|
||||
interface,
|
||||
is,
|
||||
null,
|
||||
object,
|
||||
package,
|
||||
super,
|
||||
this,
|
||||
throw,
|
||||
true,
|
||||
try,
|
||||
typealias,
|
||||
val,
|
||||
var,
|
||||
when,
|
||||
};
|
||||
|
||||
struct KotlinKeywordsStruct {
|
||||
int as;
|
||||
int class;
|
||||
int dynamic;
|
||||
int false;
|
||||
int fun;
|
||||
int in;
|
||||
int interface;
|
||||
int is;
|
||||
int null;
|
||||
int object;
|
||||
int package;
|
||||
int super;
|
||||
int this;
|
||||
int throw;
|
||||
int true;
|
||||
int try;
|
||||
int typealias;
|
||||
int val;
|
||||
int var;
|
||||
int when;
|
||||
};
|
||||
|
||||
struct KotlinKeywordsStruct createKotlinKeywordsStruct() {
|
||||
struct KotlinKeywordsStruct s = {
|
||||
.as = 0,
|
||||
.class = 0,
|
||||
.dynamic = 0,
|
||||
.false = 0,
|
||||
.fun = 0,
|
||||
.in = 0,
|
||||
.interface = 0,
|
||||
.is = 0,
|
||||
.null = 0,
|
||||
.object = 0,
|
||||
.package = 0,
|
||||
.super = 0,
|
||||
.this = 0,
|
||||
.throw = 0,
|
||||
.true = 0,
|
||||
.try = 0,
|
||||
.typealias = 0,
|
||||
.val = 0,
|
||||
.var = 0,
|
||||
.when = 0,
|
||||
};
|
||||
return s;
|
||||
}
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
import kotlin.test.*
|
||||
import mangling_keywords2.*
|
||||
import kotlinx.cinterop.useContents
|
||||
|
||||
fun box(): String {
|
||||
// Check that all Kotlin keywords are imported and mangled.
|
||||
createKotlinKeywordsStruct().useContents {
|
||||
assertEquals(0, `as`)
|
||||
assertEquals(0, `class`)
|
||||
assertEquals(0, `dynamic`)
|
||||
assertEquals(0, `false`)
|
||||
assertEquals(0, `fun`)
|
||||
assertEquals(0, `in`)
|
||||
assertEquals(0, `interface`)
|
||||
assertEquals(0, `is`)
|
||||
assertEquals(0, `null`)
|
||||
assertEquals(0, `object`)
|
||||
assertEquals(0, `package`)
|
||||
assertEquals(0, `super`)
|
||||
assertEquals(0, `this`)
|
||||
assertEquals(0, `throw`)
|
||||
assertEquals(0, `true`)
|
||||
assertEquals(0, `try`)
|
||||
assertEquals(0, `typealias`)
|
||||
assertEquals(0, `val`)
|
||||
assertEquals(0, `var`)
|
||||
assertEquals(0, `when`)
|
||||
}
|
||||
|
||||
assertEquals(KotlinKeywordsEnum.`as`, KotlinKeywordsEnum.`as`)
|
||||
assertEquals(KotlinKeywordsEnum.`class`, KotlinKeywordsEnum.`class`)
|
||||
assertEquals(KotlinKeywordsEnum.`dynamic`, KotlinKeywordsEnum.`dynamic`)
|
||||
assertEquals(KotlinKeywordsEnum.`false`, KotlinKeywordsEnum.`false`)
|
||||
assertEquals(KotlinKeywordsEnum.`fun`, KotlinKeywordsEnum.`fun`)
|
||||
assertEquals(KotlinKeywordsEnum.`in`, KotlinKeywordsEnum.`in`)
|
||||
assertEquals(KotlinKeywordsEnum.`interface`, KotlinKeywordsEnum.`interface`)
|
||||
assertEquals(KotlinKeywordsEnum.`is`, KotlinKeywordsEnum.`is`)
|
||||
assertEquals(KotlinKeywordsEnum.`null`, KotlinKeywordsEnum.`null`)
|
||||
assertEquals(KotlinKeywordsEnum.`object`, KotlinKeywordsEnum.`object`)
|
||||
assertEquals(KotlinKeywordsEnum.`package`, KotlinKeywordsEnum.`package`)
|
||||
assertEquals(KotlinKeywordsEnum.`super`, KotlinKeywordsEnum.`super`)
|
||||
assertEquals(KotlinKeywordsEnum.`this`, KotlinKeywordsEnum.`this`)
|
||||
assertEquals(KotlinKeywordsEnum.`throw`, KotlinKeywordsEnum.`throw`)
|
||||
assertEquals(KotlinKeywordsEnum.`true`, KotlinKeywordsEnum.`true`)
|
||||
assertEquals(KotlinKeywordsEnum.`try`, KotlinKeywordsEnum.`try`)
|
||||
assertEquals(KotlinKeywordsEnum.`typealias`, KotlinKeywordsEnum.`typealias`)
|
||||
assertEquals(KotlinKeywordsEnum.`val`, KotlinKeywordsEnum.`val`)
|
||||
assertEquals(KotlinKeywordsEnum.`var`, KotlinKeywordsEnum.`var`)
|
||||
assertEquals(KotlinKeywordsEnum.`when`, KotlinKeywordsEnum.`when`)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2010-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// IGNORE_NATIVE: target=linux_arm64
|
||||
// MODULE: cinterop
|
||||
// FILE: sysstat.def
|
||||
headers = sys/stat.h
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
import sysstat.*
|
||||
import kotlin.test.*
|
||||
import kotlinx.cinterop.*
|
||||
|
||||
fun box(): String {
|
||||
val statBuf = nativeHeap.alloc<stat>()
|
||||
assertEquals(0, stat("/", statBuf.ptr))
|
||||
assertEquals("0", statBuf.st_uid.toString())
|
||||
|
||||
return "OK"
|
||||
}
|
||||
Vendored
+51
@@ -0,0 +1,51 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// MODULE: cinterop
|
||||
// FILE: structAnonym.def
|
||||
---
|
||||
|
||||
/*
|
||||
* Test of return/send-by-value for aggregate type (struct or union) with anonymous inner struct or union member.
|
||||
* Specific issues: alignment, packed, nested named and anon struct/union, other anon types (named field of anon struct type; anon bitfield)
|
||||
*/
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Winitializer-overrides"
|
||||
|
||||
struct StructAnonRecordMember_ExplicitAlignment {
|
||||
char a;
|
||||
struct {
|
||||
__attribute__((aligned(4)))
|
||||
char x;
|
||||
};
|
||||
};
|
||||
|
||||
static struct StructAnonRecordMember_ExplicitAlignment retByValue_StructAnonRecordMember_ExplicitAlignment() {
|
||||
struct StructAnonRecordMember_ExplicitAlignment t = {
|
||||
.a = 'a',
|
||||
.x = 'x'
|
||||
};
|
||||
return t;
|
||||
}
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
|
||||
import kotlinx.cinterop.*
|
||||
import kotlin.test.*
|
||||
import structAnonym.*
|
||||
|
||||
fun box(): String {
|
||||
retByValue_StructAnonRecordMember_ExplicitAlignment()
|
||||
.useContents {
|
||||
assertEquals('a', a.toInt().toChar())
|
||||
assertEquals('x', x.toInt().toChar())
|
||||
}
|
||||
|
||||
return "OK"
|
||||
}
|
||||
Vendored
+52
@@ -0,0 +1,52 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// MODULE: cinterop
|
||||
// FILE: structAnonym.def
|
||||
---
|
||||
|
||||
/*
|
||||
* Test of return/send-by-value for aggregate type (struct or union) with anonymous inner struct or union member.
|
||||
* Specific issues: alignment, packed, nested named and anon struct/union, other anon types (named field of anon struct type; anon bitfield)
|
||||
*/
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Winitializer-overrides"
|
||||
|
||||
// trivial alignment: member is already aligned, but this implies implicit larger alignment of the root struct
|
||||
struct StructAnonRecordMember_ImplicitAlignment {
|
||||
int32_t a[4];
|
||||
struct {
|
||||
int b __attribute__((aligned(16)));
|
||||
};
|
||||
};
|
||||
|
||||
static struct StructAnonRecordMember_ImplicitAlignment retByValue_StructAnonRecordMember_ImplicitAlignment() {
|
||||
struct StructAnonRecordMember_ImplicitAlignment t = {
|
||||
.a = {1,2,3,4},
|
||||
.b = 42
|
||||
};
|
||||
return t;
|
||||
}
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
|
||||
import kotlinx.cinterop.*
|
||||
import kotlin.test.*
|
||||
import structAnonym.*
|
||||
|
||||
fun box(): String {
|
||||
retByValue_StructAnonRecordMember_ImplicitAlignment()
|
||||
.useContents {
|
||||
assertEquals(1, a[0])
|
||||
assertEquals(4, a[3])
|
||||
assertEquals(42, b)
|
||||
}
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// MODULE: cinterop
|
||||
// FILE: structAnonym.def
|
||||
---
|
||||
|
||||
/*
|
||||
* Test of return/send-by-value for aggregate type (struct or union) with anonymous inner struct or union member.
|
||||
* Specific issues: alignment, packed, nested named and anon struct/union, other anon types (named field of anon struct type; anon bitfield)
|
||||
*/
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Winitializer-overrides"
|
||||
|
||||
// Deep nesting
|
||||
struct StructAnonRecordMember_Nested {
|
||||
int x;
|
||||
union { // implicitly aligned to 8 bytes due to int64, or 4 bytes at 32-bit arch
|
||||
int a[2];
|
||||
struct {
|
||||
int64_t b;
|
||||
};
|
||||
};
|
||||
char z;
|
||||
double y;
|
||||
};
|
||||
|
||||
static struct StructAnonRecordMember_Nested retByValue_StructAnonRecordMember_Nested() {
|
||||
struct StructAnonRecordMember_Nested c = {
|
||||
.x = 37,
|
||||
.b = 42,
|
||||
.z = 'z',
|
||||
.y = 3.14
|
||||
};
|
||||
return c;
|
||||
}
|
||||
|
||||
static int sendByValue_StructAnonRecordMember_Nested(struct StructAnonRecordMember_Nested c) {
|
||||
return c.a[0] + 2 * c.a[1];
|
||||
}
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
|
||||
import kotlinx.cinterop.*
|
||||
import kotlin.test.*
|
||||
import structAnonym.*
|
||||
|
||||
fun box(): String {
|
||||
retByValue_StructAnonRecordMember_Nested()
|
||||
.useContents {
|
||||
assertEquals(37, x)
|
||||
assertEquals(42, b)
|
||||
assertEquals('z', z.toInt().toChar())
|
||||
assertEquals(3.14, y)
|
||||
|
||||
a[0] = 3
|
||||
a[1] = 5
|
||||
assertEquals(3 + 2*5, sendByValue_StructAnonRecordMember_Nested(this.readValue()))
|
||||
}
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// MODULE: cinterop
|
||||
// FILE: structAnonym.def
|
||||
---
|
||||
|
||||
/*
|
||||
* Test of return/send-by-value for aggregate type (struct or union) with anonymous inner struct or union member.
|
||||
* Specific issues: alignment, packed, nested named and anon struct/union, other anon types (named field of anon struct type; anon bitfield)
|
||||
*/
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Winitializer-overrides"
|
||||
|
||||
// Basic, 2 levels
|
||||
|
||||
struct StructAnonRecordMember_Complicate {
|
||||
char first; // __attribute__((aligned(16)));
|
||||
union {
|
||||
int a[2];
|
||||
union { char c1; int c2; };
|
||||
struct { char b1; int64_t b2; }; // implicit 64-bits alignment
|
||||
};
|
||||
char second __attribute__((aligned(16)));
|
||||
struct {
|
||||
char x;
|
||||
struct { int64_t b11, b12; } Y2;
|
||||
int32_t f __attribute__((aligned(16)));
|
||||
}; // __attribute__((aligned(16)));
|
||||
char last;
|
||||
};
|
||||
|
||||
#define INIT(T, x) struct T x = \
|
||||
{ \
|
||||
.first = 'a', \
|
||||
.b1 = 'b', \
|
||||
.b2 = 42, \
|
||||
.second = 's', \
|
||||
.last = 'z', \
|
||||
.f = 314, \
|
||||
.Y2 = {11, 12} \
|
||||
}
|
||||
|
||||
static struct StructAnonRecordMember_Complicate retByValue_StructAnonRecordMember_Complicate() {
|
||||
INIT(StructAnonRecordMember_Complicate, c);
|
||||
return c;
|
||||
}
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
|
||||
import kotlinx.cinterop.*
|
||||
import kotlin.test.*
|
||||
import structAnonym.*
|
||||
|
||||
fun box(): String {
|
||||
retByValue_StructAnonRecordMember_Complicate()
|
||||
.useContents{
|
||||
assertEquals('a', first.toInt().toChar())
|
||||
assertEquals('s', second.toInt().toChar())
|
||||
assertEquals('z', last.toInt().toChar())
|
||||
assertEquals('b', b1.toInt().toChar())
|
||||
assertEquals(42L, b2)
|
||||
assertEquals(314, f)
|
||||
assertEquals(11L, Y2.b11)
|
||||
}
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// MODULE: cinterop
|
||||
// FILE: structAnonym.def
|
||||
---
|
||||
|
||||
/*
|
||||
* Test of return/send-by-value for aggregate type (struct or union) with anonymous inner struct or union member.
|
||||
* Specific issues: alignment, packed, nested named and anon struct/union, other anon types (named field of anon struct type; anon bitfield)
|
||||
*/
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Winitializer-overrides"
|
||||
|
||||
union _GLKVector3
|
||||
{
|
||||
struct { float x, y, z; };
|
||||
struct { float r, g, b; };
|
||||
struct { float s, t, p; };
|
||||
float v[3];
|
||||
};
|
||||
|
||||
static union _GLKVector3 get_GLKVector3() {
|
||||
union _GLKVector3 ret = {{1, 2, 3}};
|
||||
return ret;
|
||||
}
|
||||
|
||||
static float hash_GLKVector3(union _GLKVector3 x) {
|
||||
union _GLKVector3 ret = {{1, 2, 3}};
|
||||
return x.x + 2.0f * x.y + 4.0f * x.z;
|
||||
}
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
|
||||
import kotlinx.cinterop.*
|
||||
import kotlin.test.*
|
||||
import structAnonym.*
|
||||
|
||||
fun box(): String {
|
||||
get_GLKVector3().useContents {
|
||||
assertEquals(1.0f, x)
|
||||
assertEquals(2.0f, g)
|
||||
assertEquals(3.0f, p)
|
||||
r = 0.1f
|
||||
g = 0.2f
|
||||
b = 0.3f
|
||||
assertEquals(v[0], r)
|
||||
assertEquals(v[1], g)
|
||||
assertEquals(v[2], b)
|
||||
|
||||
val ret = hash_GLKVector3(this.readValue())
|
||||
assertEquals(s + 2f * t + 4f * p , ret)
|
||||
}
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// MODULE: cinterop
|
||||
// FILE: structAnonym.def
|
||||
---
|
||||
|
||||
/*
|
||||
* Test of return/send-by-value for aggregate type (struct or union) with anonymous inner struct or union member.
|
||||
* Specific issues: alignment, packed, nested named and anon struct/union, other anon types (named field of anon struct type; anon bitfield)
|
||||
*/
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Winitializer-overrides"
|
||||
|
||||
#pragma pack(2)
|
||||
struct StructAnonRecordMember_Packed2 {
|
||||
char first;
|
||||
union {
|
||||
int a[2];
|
||||
union { char c1; int c2; };
|
||||
struct { char b1; int64_t b2; };
|
||||
};
|
||||
char second;
|
||||
struct {
|
||||
char x;
|
||||
struct { int64_t b11, b12; } Y2;
|
||||
int32_t f;
|
||||
} __attribute__((aligned(16)));
|
||||
char last;
|
||||
} __attribute__ ((packed));
|
||||
#pragma pack()
|
||||
|
||||
#define INIT(T, x) struct T x = \
|
||||
{ \
|
||||
.first = 'a', \
|
||||
.b1 = 'b', \
|
||||
.b2 = 42, \
|
||||
.second = 's', \
|
||||
.last = 'z', \
|
||||
.f = 314, \
|
||||
.Y2 = {11, 12} \
|
||||
}
|
||||
|
||||
static struct StructAnonRecordMember_Packed2 retByValue_StructAnonRecordMember_Packed2() {
|
||||
INIT(StructAnonRecordMember_Packed2, c);
|
||||
return c;
|
||||
}
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
|
||||
import kotlinx.cinterop.*
|
||||
import kotlin.test.*
|
||||
import structAnonym.*
|
||||
|
||||
fun box(): String {
|
||||
retByValue_StructAnonRecordMember_Packed2()
|
||||
.useContents{
|
||||
assertEquals('a', first.toInt().toChar())
|
||||
assertEquals('s', second.toInt().toChar())
|
||||
assertEquals('z', last.toInt().toChar())
|
||||
assertEquals('b', b1.toInt().toChar())
|
||||
assertEquals(42L, b2)
|
||||
assertEquals(314, f)
|
||||
assertEquals(11L, Y2.b11)
|
||||
}
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// MODULE: cinterop
|
||||
// FILE: structAnonym.def
|
||||
---
|
||||
|
||||
/*
|
||||
* Test of return/send-by-value for aggregate type (struct or union) with anonymous inner struct or union member.
|
||||
* Specific issues: alignment, packed, nested named and anon struct/union, other anon types (named field of anon struct type; anon bitfield)
|
||||
*/
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Winitializer-overrides"
|
||||
|
||||
// Nested struct may be packed too
|
||||
#pragma pack(2)
|
||||
struct StructAnonRecordMember_Packed2 {
|
||||
char first;
|
||||
union {
|
||||
int a[2];
|
||||
union { char c1; int c2; };
|
||||
struct { char b1; int64_t b2; };
|
||||
};
|
||||
char second;
|
||||
struct {
|
||||
char x;
|
||||
struct { int64_t b11, b12; } Y2;
|
||||
int32_t f;
|
||||
} __attribute__((aligned(16)));
|
||||
char last;
|
||||
} __attribute__ ((packed));
|
||||
#pragma pack()
|
||||
|
||||
#define INIT(T, x) struct T x = \
|
||||
{ \
|
||||
.first = 'a', \
|
||||
.b1 = 'b', \
|
||||
.b2 = 42, \
|
||||
.second = 's', \
|
||||
.last = 'z', \
|
||||
.f = 314, \
|
||||
.Y2 = {11, 12} \
|
||||
}
|
||||
|
||||
static struct StructAnonRecordMember_Packed2 retByValue_StructAnonRecordMember_Packed2() {
|
||||
INIT(StructAnonRecordMember_Packed2, c);
|
||||
return c;
|
||||
}
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
|
||||
import kotlinx.cinterop.*
|
||||
import kotlin.test.*
|
||||
import structAnonym.*
|
||||
|
||||
fun box(): String {
|
||||
retByValue_StructAnonRecordMember_Packed2()
|
||||
.useContents{
|
||||
assertEquals('a', first.toInt().toChar())
|
||||
assertEquals('s', second.toInt().toChar())
|
||||
assertEquals('z', last.toInt().toChar())
|
||||
assertEquals('b', b1.toInt().toChar())
|
||||
assertEquals(42L, b2)
|
||||
assertEquals(314, f)
|
||||
assertEquals(11L, Y2.b11)
|
||||
}
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// MODULE: cinterop
|
||||
// FILE: structAnonym.def
|
||||
---
|
||||
|
||||
/*
|
||||
* Test of return/send-by-value for aggregate type (struct or union) with anonymous inner struct or union member.
|
||||
* Specific issues: alignment, packed, nested named and anon struct/union, other anon types (named field of anon struct type; anon bitfield)
|
||||
*/
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Winitializer-overrides"
|
||||
|
||||
// Nested struct may be packed too
|
||||
#pragma pack(1)
|
||||
struct StructAnonRecordMember_PragmaPacked {
|
||||
char first;
|
||||
union {
|
||||
int a[2];
|
||||
union { char c1; int c2; };
|
||||
struct { char b1; int64_t b2; };
|
||||
};
|
||||
char second;
|
||||
struct {
|
||||
char x;
|
||||
struct { int64_t b11, b12; } Y2;
|
||||
int32_t f __attribute__((aligned(16))); // another kind of alignment
|
||||
};
|
||||
char last;
|
||||
} __attribute__ ((packed));
|
||||
#pragma pack()
|
||||
|
||||
#define INIT(T, x) struct T x = \
|
||||
{ \
|
||||
.first = 'a', \
|
||||
.b1 = 'b', \
|
||||
.b2 = 42, \
|
||||
.second = 's', \
|
||||
.last = 'z', \
|
||||
.f = 314, \
|
||||
.Y2 = {11, 12} \
|
||||
}
|
||||
|
||||
static struct StructAnonRecordMember_PragmaPacked retByValue_StructAnonRecordMember_PragmaPacked() {
|
||||
INIT(StructAnonRecordMember_PragmaPacked, c);
|
||||
return c;
|
||||
}
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
import kotlinx.cinterop.*
|
||||
import kotlin.test.*
|
||||
import structAnonym.*
|
||||
|
||||
fun box(): String {
|
||||
retByValue_StructAnonRecordMember_PragmaPacked()
|
||||
.useContents{
|
||||
assertEquals('a', first.toInt().toChar())
|
||||
assertEquals('s', second.toInt().toChar())
|
||||
assertEquals('z', last.toInt().toChar())
|
||||
assertEquals('b', b1.toInt().toChar())
|
||||
assertEquals(42L, b2)
|
||||
assertEquals(314, f)
|
||||
assertEquals(11L, Y2.b11)
|
||||
}
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,193 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// MODULE: cinterop
|
||||
// FILE: cstructs.def
|
||||
nonStrictEnums = NonStrict
|
||||
---
|
||||
typedef struct {
|
||||
int i;
|
||||
} Trivial;
|
||||
|
||||
enum E {
|
||||
R, G, B
|
||||
};
|
||||
|
||||
enum NonStrict {
|
||||
N, S, K
|
||||
};
|
||||
|
||||
struct Complex {
|
||||
unsigned int ui;
|
||||
Trivial t;
|
||||
struct Complex* next;
|
||||
enum E e;
|
||||
enum NonStrict nonStrict;
|
||||
int arr[2];
|
||||
_Bool b;
|
||||
};
|
||||
|
||||
struct __attribute__((packed)) Packed {
|
||||
int i : 1;
|
||||
enum E e : 2;
|
||||
};
|
||||
|
||||
struct Complex produceComplex() {
|
||||
struct Complex complex = {
|
||||
.ui = 128,
|
||||
.t = {1},
|
||||
.next = 0,
|
||||
.e = R,
|
||||
.nonStrict = K,
|
||||
.arr = {-51, -19},
|
||||
.b = 1
|
||||
};
|
||||
return complex;
|
||||
};
|
||||
|
||||
struct WithFlexibleArray {
|
||||
int size;
|
||||
int data[];
|
||||
};
|
||||
|
||||
struct WithFlexibleArrayWithPadding {
|
||||
int size;
|
||||
char c;
|
||||
long long data[];
|
||||
};
|
||||
|
||||
void fillArray(struct WithFlexibleArrayWithPadding *flex, int count) {
|
||||
flex->size = count;
|
||||
flex->c = '!';
|
||||
for (int i = 0; i < count; i++) {
|
||||
flex->data[i] = (((long long)i) << 32) | (i * 100);
|
||||
}
|
||||
}
|
||||
|
||||
struct WithZeroSizedArray {
|
||||
int size;
|
||||
int data[0];
|
||||
};
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
import cstructs.*
|
||||
import kotlinx.cinterop.*
|
||||
import kotlin.test.*
|
||||
|
||||
fun box(): String {
|
||||
produceComplex().useContents {
|
||||
assertEquals(ui, 128u)
|
||||
ui = 333u
|
||||
assertEquals(ui, 333u)
|
||||
|
||||
assertEquals(t.i, 1)
|
||||
t.i += 15
|
||||
assertEquals(t.i, 16)
|
||||
|
||||
assertEquals(next, null)
|
||||
next = this.ptr
|
||||
assertEquals(next, this.ptr)
|
||||
// Check null pointer because it has Nothing? type.
|
||||
next = null
|
||||
assertEquals(next, null)
|
||||
|
||||
assertEquals(e, E.R)
|
||||
e = E.G
|
||||
assertEquals(e, E.G)
|
||||
|
||||
assertEquals(K, nonStrict)
|
||||
nonStrict = S
|
||||
assertEquals(S, nonStrict)
|
||||
|
||||
assertEquals(arr[0], -51)
|
||||
assertEquals(arr[1], -19)
|
||||
arr[0] = 51
|
||||
arr[1] = 19
|
||||
assertEquals(arr[0], 51)
|
||||
assertEquals(arr[1], 19)
|
||||
|
||||
assertEquals(true, b)
|
||||
b = false
|
||||
assertEquals(false, b)
|
||||
|
||||
// Check that subtyping via Nothing-returning functions does not break compiler.
|
||||
assertFailsWith<NotImplementedError> {
|
||||
ui = TODO()
|
||||
t.i = TODO()
|
||||
next = TODO()
|
||||
e = TODO()
|
||||
nonStrict = TODO()
|
||||
b = TODO()
|
||||
}
|
||||
}
|
||||
memScoped {
|
||||
val packed = alloc<Packed>()
|
||||
packed.i = -1
|
||||
assertEquals(-1, packed.i)
|
||||
packed.e = E.R
|
||||
assertEquals(E.R, packed.e)
|
||||
// Check that subtyping via Nothing-returning functions does not break compiler.
|
||||
assertFailsWith<NotImplementedError> {
|
||||
packed.i = TODO()
|
||||
packed.e = TODO()
|
||||
}
|
||||
}
|
||||
// Check that generics doesn't break anything.
|
||||
checkEnumSubTyping(E.R)
|
||||
checkIntSubTyping(630090)
|
||||
|
||||
memScoped {
|
||||
val SIZE = 10
|
||||
val flex = alloc(sizeOf<WithFlexibleArray>() + sizeOf<IntVar>() * SIZE, alignOf<WithFlexibleArray>()).reinterpret<WithFlexibleArray>()
|
||||
flex.size = SIZE
|
||||
for (i in 0 until SIZE) {
|
||||
flex.data[i] = i
|
||||
}
|
||||
assertEquals(SIZE, flex.size)
|
||||
for (i in 0 until SIZE) {
|
||||
assertEquals(i, flex.data[i])
|
||||
}
|
||||
}
|
||||
|
||||
memScoped {
|
||||
val SIZE = 10
|
||||
val flex = alloc(sizeOf<WithZeroSizedArray>() + sizeOf<IntVar>() * SIZE, alignOf<WithZeroSizedArray>()).reinterpret<WithZeroSizedArray>()
|
||||
assertEquals(4, sizeOf<WithZeroSizedArray>())
|
||||
assertEquals(4, alignOf<WithZeroSizedArray>())
|
||||
flex.size = SIZE
|
||||
for (i in 0 until SIZE) {
|
||||
flex.data[i] = i
|
||||
}
|
||||
assertEquals(SIZE, flex.size)
|
||||
for (i in 0 until SIZE) {
|
||||
assertEquals(i, flex.data[i])
|
||||
}
|
||||
}
|
||||
|
||||
memScoped {
|
||||
val SIZE = 10
|
||||
assertEquals(8, sizeOf<WithFlexibleArrayWithPadding>())
|
||||
assertEquals(8, alignOf<WithFlexibleArrayWithPadding>())
|
||||
val flex = alloc(sizeOf<WithFlexibleArrayWithPadding>() + sizeOf<LongVar>() * SIZE, alignOf<WithFlexibleArrayWithPadding>())
|
||||
.reinterpret<WithFlexibleArrayWithPadding>()
|
||||
fillArray(flex.ptr, SIZE)
|
||||
assertEquals(SIZE, flex.size)
|
||||
assertEquals('!'.code.toByte(), flex.c);
|
||||
for (i in 0 until SIZE) {
|
||||
assertEquals((i.toLong() shl 32) or (i.toLong() * 100), flex.data[i])
|
||||
}
|
||||
}
|
||||
return "OK"
|
||||
}
|
||||
|
||||
fun <T : E> checkEnumSubTyping(e: T) = memScoped {
|
||||
val s = alloc<Complex>()
|
||||
s.e = e
|
||||
}
|
||||
|
||||
fun <T : Int> checkIntSubTyping(x: T) = memScoped {
|
||||
val s = alloc<Trivial>()
|
||||
s.i = x
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// MODULE: cinterop
|
||||
// FILE: ctypes.def
|
||||
---
|
||||
|
||||
// KT-28065
|
||||
struct StructWithConstFields {
|
||||
int x;
|
||||
const int y;
|
||||
};
|
||||
|
||||
struct StructWithConstFields getStructWithConstFields() {
|
||||
struct StructWithConstFields result = { 111, 222 };
|
||||
return result;
|
||||
}
|
||||
|
||||
enum ForwardDeclaredEnum;
|
||||
enum ForwardDeclaredEnum {
|
||||
ZERO, ONE, TWO
|
||||
};
|
||||
|
||||
static int vlaSum(int size, int array[size]) {
|
||||
int result = 0;
|
||||
for (int i = 0; i < size; ++i) {
|
||||
result += array[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static int vlaSum2D(int size, int array[][size]) {
|
||||
int result = 0;
|
||||
for (int i = 0; i < size; ++i) {
|
||||
for (int j = 0; j < size; ++j) {
|
||||
result += array[i][j];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static int vlaSum2DBothDimensions(int rows, int columns, int array[rows][columns]) {
|
||||
int result = 0;
|
||||
for (int i = 0; i < rows; ++i) {
|
||||
for (int j = 0; j < columns; ++j) {
|
||||
result += array[i][j];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
// Not supported by clang:
|
||||
static int vlaSum2DForward(int size; int array[][size], int size) {
|
||||
return vlaSum2D(size, array);
|
||||
}
|
||||
*/
|
||||
|
||||
// "Strict" enums heuristic based on whether enum constants are defined explicitly:
|
||||
enum StrictEnum1 {
|
||||
StrictEnum1A,
|
||||
StrictEnum1B
|
||||
};
|
||||
|
||||
enum StrictEnum2 {
|
||||
StrictEnum2A __attribute__((unused)),
|
||||
StrictEnum2B __attribute__((unused))
|
||||
};
|
||||
|
||||
enum NonStrictEnum1 {
|
||||
NonStrictEnum1A = 0,
|
||||
NonStrictEnum1B __attribute__((unused))
|
||||
};
|
||||
|
||||
enum NonStrictEnum2 {
|
||||
NonStrictEnum2A,
|
||||
NonStrictEnum2B __attribute__((unused)) = 1
|
||||
};
|
||||
|
||||
// KT-34025
|
||||
typedef char Char;
|
||||
enum EnumCharBase : Char {
|
||||
EnumCharBaseA,
|
||||
EnumCharBaseB
|
||||
};
|
||||
|
||||
static int sendEnum(enum EnumCharBase x) {
|
||||
return (int)x + 2;
|
||||
}
|
||||
|
||||
enum EnumExplicitChar : char {
|
||||
EnumExplicitCharA = 'a',
|
||||
EnumExplicitCharB = 'b',
|
||||
EnumExplicitCharDup = 'a'
|
||||
};
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
import kotlinx.cinterop.*
|
||||
import kotlin.native.*
|
||||
import kotlin.test.*
|
||||
import ctypes.*
|
||||
|
||||
fun box(): String {
|
||||
getStructWithConstFields().useContents {
|
||||
assertEquals(111, x)
|
||||
assertEquals(222, y)
|
||||
}
|
||||
|
||||
assertEquals(1u, ForwardDeclaredEnum.ONE.value)
|
||||
|
||||
assertEquals(6, vlaSum(3, cValuesOf(1, 2, 3)))
|
||||
assertEquals(10, vlaSum2D(2, cValuesOf(1, 2, 3, 4)))
|
||||
assertEquals(21, vlaSum2DBothDimensions(2, 3, cValuesOf(1, 2, 3, 4, 5, 6)))
|
||||
|
||||
// Not supported by clang:
|
||||
// assertEquals(10, vlaSum2DForward(cValuesOf(1, 2, 3, 4), 2))
|
||||
|
||||
assertEquals(0u, StrictEnum1.StrictEnum1A.value)
|
||||
assertEquals(1u, StrictEnum2.StrictEnum2B.value)
|
||||
assertEquals(0u, NonStrictEnum1A)
|
||||
assertEquals(1u, NonStrictEnum2B)
|
||||
assertEquals(1, EnumCharBase.EnumCharBaseB.value)
|
||||
assertEquals(3, sendEnum(EnumCharBase.EnumCharBaseB))
|
||||
assertEquals('a'.toByte(), EnumExplicitCharA)
|
||||
assertEquals('b'.toByte(), EnumExplicitCharB)
|
||||
assertEquals(EnumExplicitCharA, EnumExplicitCharDup)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// MODULE: cinterop
|
||||
// FILE: cunion.def
|
||||
---
|
||||
typedef union {
|
||||
short s;
|
||||
long long ll;
|
||||
} BasicUnion;
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
int i;
|
||||
float f;
|
||||
} as;
|
||||
} StructWithUnion;
|
||||
|
||||
typedef union {
|
||||
unsigned int i : 31;
|
||||
unsigned char b : 1;
|
||||
} Packed;
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
|
||||
@file:OptIn(kotlin.experimental.ExperimentalNativeApi::class, kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
import cunion.*
|
||||
import kotlinx.cinterop.*
|
||||
import kotlin.native.*
|
||||
import kotlin.test.*
|
||||
|
||||
fun box(): String {
|
||||
memScoped {
|
||||
val basicUnion = alloc<BasicUnion>()
|
||||
for (value in Short.MIN_VALUE..Short.MAX_VALUE) {
|
||||
basicUnion.ll = value.toLong()
|
||||
val expected = if (Platform.isLittleEndian) {
|
||||
value
|
||||
} else {
|
||||
value.toLong() ushr (Long.SIZE_BITS - Short.SIZE_BITS)
|
||||
}
|
||||
assertEquals(expected.toShort(), basicUnion.s)
|
||||
}
|
||||
}
|
||||
memScoped {
|
||||
val struct = alloc<StructWithUnion>()
|
||||
struct.`as`.i = Float.NaN.toRawBits()
|
||||
assertEquals(Float.NaN, struct.`as`.f)
|
||||
}
|
||||
memScoped {
|
||||
val union = alloc<Packed>()
|
||||
union.b = 1u
|
||||
var expected = if (Platform.isLittleEndian) {
|
||||
1u
|
||||
} else {
|
||||
1u shl (Int.SIZE_BITS - Byte.SIZE_BITS)
|
||||
}
|
||||
assertEquals(expected, union.i)
|
||||
union.i = 0u
|
||||
assertEquals(0u, union.b)
|
||||
}
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// MODULE: cinterop
|
||||
// FILE: cunsupported.def
|
||||
compilerOpts = -mno-xsave
|
||||
|
||||
---
|
||||
|
||||
static void noAttr() {}
|
||||
__attribute__((always_inline)) noTargetAttr() {}
|
||||
|
||||
__attribute__((always_inline, __target__("xsave"))) void plainAttrs1() {}
|
||||
__attribute__((__target__("xsave"), always_inline)) void plainAttrs2() {}
|
||||
|
||||
#define TARGET __target__
|
||||
|
||||
__attribute__((always_inline, TARGET("xsave"))) void macroAttr1() {}
|
||||
__attribute__((TARGET("xsave"), always_inline)) void macroAttr2() {}
|
||||
|
||||
#define TARGET_ATTR __target__("xsave")
|
||||
|
||||
__attribute__((TARGET_ATTR, always_inline)) void macroAttr3() {}
|
||||
__attribute__((always_inline, TARGET_ATTR)) void macroAttr4() {}
|
||||
|
||||
#define ALL_ATTRS1 __attribute__((always_inline, __target__("xsave")))
|
||||
|
||||
ALL_ATTRS1 void macroAttr5() {}
|
||||
|
||||
#define ALL_ATTRS2 __attribute__((always_inline, __target__("xsave")))
|
||||
|
||||
ALL_ATTRS2 void macroAttr6() {}
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
import kotlin.test.*
|
||||
import cunsupported.*
|
||||
|
||||
fun box(): String {
|
||||
noAttr()
|
||||
noTargetAttr()
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// MODULE: cinterop
|
||||
// FILE: cvalues.def
|
||||
---
|
||||
_Bool isNullString(const char* str) {
|
||||
return str == (const char*)0;
|
||||
}
|
||||
|
||||
typedef const short* LPCWSTR;
|
||||
|
||||
_Bool isNullWString(LPCWSTR str) {
|
||||
return str == (LPCWSTR)0;
|
||||
}
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
import kotlinx.cinterop.*
|
||||
import kotlin.test.*
|
||||
import cvalues.*
|
||||
|
||||
fun box(): String {
|
||||
assertTrue(isNullString(null))
|
||||
assertTrue(isNullWString(null))
|
||||
assertFalse(isNullString("a"))
|
||||
assertFalse(isNullWString("b"))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// MODULE: cinterop
|
||||
// FILE: cvectors.def
|
||||
---
|
||||
typedef float __attribute__ ((__vector_size__ (16))) KVector4f;
|
||||
typedef int __attribute__ ((__vector_size__ (16))) KVector4i32;
|
||||
|
||||
struct Complex {
|
||||
unsigned int ui;
|
||||
KVector4f vec4f;
|
||||
struct Complex* next;
|
||||
int arr[2];
|
||||
};
|
||||
|
||||
struct Complex produceComplexVector() {
|
||||
struct Complex complex = {
|
||||
.ui = 128,
|
||||
.vec4f = {1.0, 1.0, 1.0, 1.0},
|
||||
.next = 0,
|
||||
.arr = {-51, -19}
|
||||
};
|
||||
return complex;
|
||||
};
|
||||
|
||||
static float sendV4F(KVector4f v) {
|
||||
return v[0] + 2 * v[1] + 4 * v[2] + 8 * v[3];
|
||||
}
|
||||
|
||||
static int sendV4I(KVector4i32 v) {
|
||||
return v[0] + 2 * v[1] + 4 * v[2] + 8 * v[3];
|
||||
}
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class, kotlin.experimental.ExperimentalNativeApi::class)
|
||||
|
||||
import kotlinx.cinterop.*
|
||||
import kotlinx.cinterop.vectorOf
|
||||
import kotlin.native.*
|
||||
import kotlin.test.*
|
||||
import cvectors.*
|
||||
|
||||
fun box(): String {
|
||||
produceComplexVector().useContents {
|
||||
assertEquals(vec4f, vectorOf(1.0f, 1.0f, 1.0f, 1.0f))
|
||||
vec4f = vectorOf(0.0f, 0.0f, 0.0f, 0.0f)
|
||||
assertEquals(vec4f, vectorOf(0.0f, 0.0f, 0.0f, 0.0f))
|
||||
}
|
||||
|
||||
// FIXME: KT-36285
|
||||
if (Platform.osFamily != OsFamily.LINUX || Platform.cpuArchitecture != CpuArchitecture.ARM32) {
|
||||
assertEquals(49, sendV4I(vectorOf(1, 2, 3, 4)))
|
||||
}
|
||||
assertEquals(49, (sendV4F(vectorOf(1f, 2f, 3f, 4f)) + 0.00001).toInt())
|
||||
|
||||
memScoped {
|
||||
val vector = alloc<KVector4i32Var>().also {
|
||||
it.value = vectorOf(1, 2, 3, 4)
|
||||
}
|
||||
assertEquals(vector.value, vectorOf(1, 2, 3, 4))
|
||||
}
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright 2010-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
// May need disabling when gcSchedulerType=aggressive . since it may be too slow
|
||||
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// MODULE: cinterop
|
||||
// FILE: bitfields.def
|
||||
---
|
||||
enum B2 {
|
||||
ZERO, ONE, TWO, THREE
|
||||
};
|
||||
|
||||
enum E : short {
|
||||
A, B
|
||||
};
|
||||
|
||||
struct __attribute__((packed)) S {
|
||||
long long x1 : 1;
|
||||
enum B2 x2 : 2;
|
||||
unsigned short x3 : 3;
|
||||
unsigned int x4 : 4;
|
||||
int x5 : 5;
|
||||
long long x6 : 63;
|
||||
enum E x7: 2;
|
||||
_Bool x8 : 1;
|
||||
struct { int x9:4; };
|
||||
};
|
||||
|
||||
static long long getX1(struct S* s) { return s->x1; }
|
||||
static enum B2 getX2(struct S* s) { return s->x2; }
|
||||
static unsigned short getX3(struct S* s) { return s->x3; }
|
||||
static unsigned int getX4(struct S* s) { return s->x4; }
|
||||
static int getX5(struct S* s) { return s->x5; }
|
||||
static long long getX6(struct S* s) { return s->x6; }
|
||||
static enum E getX7(struct S* s) { return s->x7; }
|
||||
static _Bool getX8(struct S* s) { return s->x8; }
|
||||
static int getX9(struct S* s) { return s->x9; }
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
import bitfields.*
|
||||
import kotlinx.cinterop.*
|
||||
|
||||
fun assertEquals(value1: Any?, value2: Any?) {
|
||||
if (value1 != value2)
|
||||
throw AssertionError("Expected $value1, got $value2")
|
||||
}
|
||||
|
||||
fun check(s: S, x1: Long, x2: B2, x3: UShort, x4: UInt, x5: Int, x6: Long, x7: E, x8: Boolean, x9: Int) {
|
||||
assertEquals(x1, s.x1)
|
||||
assertEquals(x1, getX1(s.ptr))
|
||||
|
||||
assertEquals(x2, s.x2)
|
||||
assertEquals(x2, getX2(s.ptr))
|
||||
|
||||
assertEquals(x3, s.x3)
|
||||
assertEquals(x3, getX3(s.ptr))
|
||||
|
||||
assertEquals(x4, s.x4)
|
||||
assertEquals(x4, getX4(s.ptr))
|
||||
|
||||
assertEquals(x5, s.x5)
|
||||
assertEquals(x5, getX5(s.ptr))
|
||||
|
||||
assertEquals(x6, s.x6)
|
||||
assertEquals(x6, getX6(s.ptr))
|
||||
|
||||
assertEquals(x7, s.x7)
|
||||
assertEquals(x7, getX7(s.ptr))
|
||||
|
||||
assertEquals(x8, s.x8)
|
||||
assertEquals(x8, getX8(s.ptr))
|
||||
|
||||
assertEquals(x9, s.x9)
|
||||
assertEquals(x9, getX9(s.ptr))
|
||||
}
|
||||
|
||||
fun assign(s: S, x1: Long, x2: B2, x3: UShort, x4: UInt, x5: Int, x6: Long, x7: E, x8: Boolean, x9: Int) {
|
||||
s.x1 = x1
|
||||
s.x2 = x2
|
||||
s.x3 = x3
|
||||
s.x4 = x4
|
||||
s.x5 = x5
|
||||
s.x6 = x6
|
||||
s.x7 = x7
|
||||
s.x8 = x8
|
||||
s.x9 = x9
|
||||
}
|
||||
|
||||
fun assignReversed(s: S, x1: Long, x2: B2, x3: UShort, x4: UInt, x5: Int, x6: Long, x7: E, x8: Boolean, x9: Int) {
|
||||
s.x9 = x9
|
||||
s.x8 = x8
|
||||
s.x7 = x7
|
||||
s.x6 = x6
|
||||
s.x5 = x5
|
||||
s.x4 = x4
|
||||
s.x3 = x3
|
||||
s.x2 = x2
|
||||
s.x1 = x1
|
||||
}
|
||||
|
||||
fun test(s: S, x1: Long, x2: B2, x3: UShort, x4: UInt, x5: Int, x6: Long, x7: E, x8: Boolean, x9: Int) {
|
||||
assign(s, x1, x2, x3, x4, x5, x6, x7, x8, x9)
|
||||
check(s, x1, x2, x3, x4, x5, x6, x7, x8, x9)
|
||||
|
||||
assignReversed(s, x1, x2, x3, x4, x5, x6, x7, x8, x9)
|
||||
check(s, x1, x2, x3, x4, x5, x6, x7, x8, x9)
|
||||
|
||||
// Also check with some insignificant bits modified:
|
||||
|
||||
assign(s, x1 + 2, x2, (x3 + 8u).toUShort(), x4 - 16u, x5 + 32, x6 + Long.MIN_VALUE, x7, x8, x9 + 16)
|
||||
check(s, x1, x2, x3, x4, x5, x6, x7, x8, x9)
|
||||
|
||||
assignReversed(s, x1 + 2, x2, (x3 + 8u).toUShort(), x4 - 16u, x5 + 32, x6 + Long.MIN_VALUE, x7, x8, x9 + 16)
|
||||
check(s, x1, x2, x3, x4, x5, x6, x7, x8, x9)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
memScoped {
|
||||
val s = alloc<S>()
|
||||
for (x1 in -1L..0L)
|
||||
for (x2 in arrayOf(B2.ZERO, B2.ONE, B2.THREE))
|
||||
for (x3 in ushortArrayOf(0u, 2u, 7u))
|
||||
for (x4 in uintArrayOf(0u, 6u, 15u))
|
||||
for (x5 in intArrayOf(-16, -1, 0, 5, 15))
|
||||
for (x6 in longArrayOf(Long.MIN_VALUE/2, -325L, 0, 1L shl 48, Long.MAX_VALUE/2))
|
||||
for (x7 in E.values())
|
||||
for (x8 in arrayOf(false, true))
|
||||
for (x9 in intArrayOf(-8, -1, 0, 5, 7)) // 4 bits width
|
||||
test(s, x1, x2, x3.toUShort(), x4, x5, x6, x7, x8, x9)
|
||||
}
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Copyright 2010-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// MODULE: cinterop
|
||||
// FILE: ccallbacksAndVarargs.def
|
||||
---
|
||||
#include <stdarg.h>
|
||||
|
||||
struct S {
|
||||
int x;
|
||||
};
|
||||
|
||||
static int getX(struct S (*callback)(void)) {
|
||||
return callback().x;
|
||||
}
|
||||
|
||||
static void applyCallback(struct S s, void (*callback)(struct S)) {
|
||||
callback(s);
|
||||
}
|
||||
|
||||
static struct S makeS(int x, ...) {
|
||||
return (struct S){ x };
|
||||
}
|
||||
|
||||
enum E {
|
||||
ZERO, ONE, TWO
|
||||
};
|
||||
|
||||
static enum E makeE(int ordinal, ...) {
|
||||
return ordinal;
|
||||
}
|
||||
|
||||
struct Args {
|
||||
char a1;
|
||||
char a2;
|
||||
short a3;
|
||||
int a4;
|
||||
long long a5;
|
||||
float a6;
|
||||
double a7;
|
||||
void* a8;
|
||||
unsigned char a9;
|
||||
unsigned short a10;
|
||||
unsigned int a11;
|
||||
unsigned long long a12;
|
||||
enum E a13;
|
||||
struct S a14;
|
||||
void* a15;
|
||||
};
|
||||
|
||||
static struct Args getVarargs(int ignore, ...) {
|
||||
va_list args;
|
||||
va_start(args, ignore);
|
||||
|
||||
struct Args result = {
|
||||
va_arg(args, char),
|
||||
va_arg(args, char),
|
||||
va_arg(args, short),
|
||||
va_arg(args, int),
|
||||
va_arg(args, long long),
|
||||
va_arg(args, double),
|
||||
va_arg(args, double),
|
||||
va_arg(args, void*),
|
||||
va_arg(args, unsigned char),
|
||||
va_arg(args, unsigned short),
|
||||
va_arg(args, unsigned int),
|
||||
va_arg(args, unsigned long long),
|
||||
va_arg(args, enum E),
|
||||
va_arg(args, struct S),
|
||||
va_arg(args, void*)
|
||||
};
|
||||
|
||||
va_end(args);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int sum(int first, int second) {
|
||||
return first + second;
|
||||
}
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
import kotlin.test.*
|
||||
import kotlinx.cinterop.*
|
||||
import ccallbacksAndVarargs.*
|
||||
|
||||
fun box(): String {
|
||||
testStructCallbacks()
|
||||
testVarargs()
|
||||
testCallableReferences()
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
fun testStructCallbacks() {
|
||||
assertEquals(42, getX(staticCFunction { -> cValue<S> { x = 42 } }))
|
||||
applyCallback(cValue { x = 17 }, staticCFunction { it: CValue<S> ->
|
||||
assertEquals(17, it.useContents { x })
|
||||
})
|
||||
|
||||
assertEquals(66, makeS(66, 111).useContents { x })
|
||||
}
|
||||
|
||||
fun testVarargs() {
|
||||
assertEquals(E.ONE, makeE(1))
|
||||
|
||||
getVarargs(
|
||||
0,
|
||||
true,
|
||||
2.toByte(),
|
||||
Short.MIN_VALUE,
|
||||
42,
|
||||
Long.MAX_VALUE,
|
||||
3.14f,
|
||||
2.71,
|
||||
0x1234ABCDL.toCPointer<COpaque>(),
|
||||
UByte.MAX_VALUE,
|
||||
22.toUShort(),
|
||||
111u,
|
||||
ULong.MAX_VALUE,
|
||||
E.TWO,
|
||||
cValue<S> { x = 15 },
|
||||
null
|
||||
).useContents {
|
||||
assertEquals(1, a1)
|
||||
assertEquals(2.toByte(), a2)
|
||||
assertEquals(Short.MIN_VALUE, a3)
|
||||
assertEquals(42, a4)
|
||||
assertEquals(Long.MAX_VALUE, a5)
|
||||
assertEquals(3.14f, a6)
|
||||
assertEquals(2.71, a7)
|
||||
assertEquals(0x1234ABCDL, a8.toLong())
|
||||
assertEquals(UByte.MAX_VALUE, a9)
|
||||
assertEquals(22.toUShort(), a10)
|
||||
assertEquals(111u, a11)
|
||||
assertEquals(ULong.MAX_VALUE, a12)
|
||||
assertEquals(E.TWO, a13)
|
||||
assertEquals(15, a14.x)
|
||||
assertEquals(null, a15)
|
||||
}
|
||||
}
|
||||
|
||||
fun testCallableReferences() {
|
||||
val sumRef = ::sum
|
||||
assertEquals(3, sumRef(1, 2))
|
||||
|
||||
val sumPtr = staticCFunction(::sum)
|
||||
assertEquals(7, sumPtr(3, 4))
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// MODULE: cinterop
|
||||
// FILE: cenums.def
|
||||
---
|
||||
enum E {
|
||||
A, B, C
|
||||
};
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
|
||||
// !LANGUAGE: +EnumEntries
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
import cenums.*
|
||||
import kotlinx.cinterop.*
|
||||
import kotlin.test.*
|
||||
|
||||
@OptIn(kotlin.ExperimentalStdlibApi::class)
|
||||
fun box(): String {
|
||||
memScoped {
|
||||
val e = alloc<E.Var>()
|
||||
e.value = E.C
|
||||
assertEquals(E.C, e.value)
|
||||
|
||||
assertFailsWith<NotImplementedError> {
|
||||
e.value = TODO()
|
||||
}
|
||||
}
|
||||
val values = E.values()
|
||||
assertEquals(values[0], E.A)
|
||||
assertEquals(values[1], E.B)
|
||||
assertEquals(values[2], E.C)
|
||||
// TODO: temporariry commented. Task for investigation is KT-56107
|
||||
// val entries = E.entries
|
||||
// assertEquals(entries[0], E.A)
|
||||
// assertEquals(entries[1], E.B)
|
||||
// assertEquals(entries[2], E.C)
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// MODULE: cinterop
|
||||
// FILE: cCallback.def
|
||||
language = C
|
||||
---
|
||||
extern char* sb;
|
||||
void runAndCatch(void(*f)(void));
|
||||
|
||||
// FILE: cCallback.cpp
|
||||
#include <stdio.h>
|
||||
|
||||
char* sb = nullptr;
|
||||
extern "C" void runAndCatch(void(*f)(void)) {
|
||||
try {
|
||||
f();
|
||||
} catch (...) {
|
||||
sb = "OK";
|
||||
}
|
||||
}
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
import kotlinx.cinterop.staticCFunction
|
||||
import kotlinx.cinterop.toKString
|
||||
import cCallback.runAndCatch
|
||||
import cCallback.sb
|
||||
|
||||
fun throwingCallback() {
|
||||
throw IllegalStateException("Kotlin Exception!")
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
runAndCatch(staticCFunction(::throwingCallback))
|
||||
return sb?.toKString() ?: "FAIL"
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
// This test mostly checks frontend behaviour.
|
||||
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// MODULE: cinterop
|
||||
// FILE: cForwardDeclarations.def
|
||||
---
|
||||
struct StructDeclared;
|
||||
struct StructDefined { int x; };
|
||||
|
||||
int useStructDeclared(struct StructDeclared* declared) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int useStructDefined(struct StructDefined* defined) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
import cForwardDeclarations.*
|
||||
import cnames.structs.StructDeclared
|
||||
|
||||
import kotlin.test.assertEquals
|
||||
import kotlinx.cinterop.COpaque
|
||||
import kotlinx.cinterop.CStructVar
|
||||
import kotlinx.cinterop.ptr
|
||||
// The test should also check that these references can't be resolved, but the test infra doesn't support this yet:
|
||||
// import cForwardDeclarations.StructUndeclared
|
||||
// import cnames.structs.StructUndeclared // Supported in K1 though.
|
||||
|
||||
fun <T1 : T2, T2> checkSubtype2() {}
|
||||
|
||||
// Here we rely on frontend reporting conflicting overloads if some of these types turn out to be the same.
|
||||
fun checkDifferentTypes(s: StructDeclared?) = 1
|
||||
fun checkDifferentTypes(s: StructDefined?) = 2
|
||||
|
||||
fun box(): String {
|
||||
checkSubtype2<StructDeclared, COpaque>()
|
||||
|
||||
checkSubtype2<StructDefined, CStructVar>()
|
||||
|
||||
val declared: StructDeclared? = null
|
||||
val defined: StructDefined? = null
|
||||
|
||||
assertEquals(1, checkDifferentTypes(declared))
|
||||
assertEquals(2, checkDifferentTypes(defined))
|
||||
|
||||
assertEquals(-1, useStructDeclared(declared?.ptr))
|
||||
assertEquals(-2, useStructDefined(defined?.ptr))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
// This test mostly checks frontend behaviour.
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// MODULE: cinterop1
|
||||
// FILE: cForwardDeclarationsTwoLibs1.def
|
||||
---
|
||||
struct StructDeclaredUndeclared;
|
||||
struct StructDeclaredDeclared;
|
||||
struct StructDeclaredDefined;
|
||||
struct StructDefinedUndeclared {};
|
||||
struct StructDefinedDeclared {};
|
||||
struct StructDefinedDefined {};
|
||||
|
||||
int use1StructDeclaredUndeclared(struct StructDeclaredUndeclared* declaredUndeclared) { return -3; }
|
||||
int use1StructDeclaredDeclared(struct StructDeclaredDeclared* declaredDeclared) { return -4; }
|
||||
int use1StructDeclaredDefined(struct StructDeclaredDefined* declaredDefined) { return -5; }
|
||||
int use1StructDefinedUndeclared(struct StructDefinedUndeclared* definedUndeclared) { return -6; }
|
||||
int use1StructDefinedDeclared(struct StructDefinedDeclared* definedDeclared) { return -7; }
|
||||
int use1StructDefinedDefined(struct StructDefinedDefined* definedDefined) { return -8; }
|
||||
|
||||
// MODULE: cinterop2
|
||||
// FILE: cForwardDeclarationsTwoLibs2.def
|
||||
---
|
||||
struct StructUndeclaredDeclared;
|
||||
struct StructUndeclaredDefined {};
|
||||
struct StructDeclaredDeclared;
|
||||
struct StructDeclaredDefined {};
|
||||
struct StructDefinedDeclared;
|
||||
struct StructDefinedDefined {};
|
||||
|
||||
int use2StructUndeclaredDeclared(struct StructUndeclaredDeclared* undeclaredDeclared) { return 1; }
|
||||
int use2StructUndeclaredDefined(struct StructUndeclaredDefined* undeclaredDefined) { return 2; }
|
||||
int use2StructDeclaredDeclared(struct StructDeclaredDeclared* declaredDeclared) { return 4; }
|
||||
int use2StructDeclaredDefined(struct StructDeclaredDefined* declaredDefined) { return 5; }
|
||||
int use2StructDefinedDeclared(struct StructDefinedDeclared* definedDeclared) { return 7; }
|
||||
int use2StructDefinedDefined(struct StructDefinedDefined* definedDefined) { return 8; }
|
||||
|
||||
// MODULE: main(cinterop1, cinterop2)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
import cForwardDeclarationsTwoLibs1.*
|
||||
import cForwardDeclarationsTwoLibs2.*
|
||||
import cnames.structs.StructUndeclaredDeclared
|
||||
import cnames.structs.StructDeclaredUndeclared
|
||||
import cnames.structs.StructDeclaredDeclared
|
||||
|
||||
import kotlin.test.assertEquals
|
||||
import kotlinx.cinterop.COpaque
|
||||
import kotlinx.cinterop.CPointed
|
||||
import kotlinx.cinterop.CStructVar
|
||||
import kotlinx.cinterop.ptr
|
||||
// The test should also check that these references can't be resolved, but the test infra doesn't support this yet:
|
||||
// import cForwardDeclarationsTwoLibs1.StructUndeclaredUndeclared
|
||||
// import cForwardDeclarationsTwoLibs1.StructUndeclaredDeclared
|
||||
// import cForwardDeclarationsTwoLibs1.StructUndeclaredDefined
|
||||
// import cForwardDeclarationsTwoLibs2.StructUndeclaredUndeclared
|
||||
// import cForwardDeclarationsTwoLibs2.StructDeclaredUndeclared
|
||||
// import cForwardDeclarationsTwoLibs2.StructDefinedUndeclared
|
||||
// import cnames.structs.StructUndeclaredUndeclared // Supported in K1 though.
|
||||
|
||||
fun <T1 : T2, T2> checkSubtype2() {}
|
||||
|
||||
// Here we rely on frontend reporting conflicting overloads if some of these types turn out to be the same.
|
||||
fun checkDifferentTypes(s: StructUndeclaredDeclared?) = 1
|
||||
fun checkDifferentTypes(s: StructUndeclaredDefined?) = 2
|
||||
fun checkDifferentTypes(s: StructDeclaredUndeclared?) = 3
|
||||
fun checkDifferentTypes(s: StructDeclaredDeclared?) = 4
|
||||
fun checkDifferentTypes(s: StructDeclaredDefined?) = 5
|
||||
fun checkDifferentTypes(s: StructDefinedUndeclared?) = 6
|
||||
fun checkDifferentTypes(s: StructDefinedDeclared?) = 7
|
||||
fun checkDifferentTypes(s: cForwardDeclarationsTwoLibs1.StructDefinedDefined?) = 8
|
||||
fun checkDifferentTypes(s: cForwardDeclarationsTwoLibs2.StructDefinedDefined?) = 9
|
||||
|
||||
fun box(): String {
|
||||
checkSubtype2<StructUndeclaredDeclared, COpaque>()
|
||||
|
||||
checkSubtype2<StructUndeclaredDefined, CStructVar>()
|
||||
|
||||
checkSubtype2<StructDeclaredUndeclared, COpaque>()
|
||||
|
||||
checkSubtype2<StructDeclaredDeclared, COpaque>()
|
||||
|
||||
checkSubtype2<cnames.structs.StructDeclaredDefined, CPointed>()
|
||||
checkSubtype2<StructDeclaredDefined, CStructVar>()
|
||||
|
||||
checkSubtype2<StructDefinedUndeclared, CStructVar>()
|
||||
|
||||
checkSubtype2<cnames.structs.StructDefinedDeclared, CPointed>()
|
||||
checkSubtype2<StructDefinedDeclared, CStructVar>()
|
||||
|
||||
checkSubtype2<cForwardDeclarationsTwoLibs1.StructDefinedDefined, CStructVar>()
|
||||
checkSubtype2<cForwardDeclarationsTwoLibs2.StructDefinedDefined, CStructVar>()
|
||||
|
||||
val undeclaredDeclared: StructUndeclaredDeclared? = null
|
||||
val undeclaredDefined: StructUndeclaredDefined? = null
|
||||
val declaredUndeclared: StructDeclaredUndeclared? = null
|
||||
val declaredDeclared: StructDeclaredDeclared? = null
|
||||
val cnamesDeclaredDefined: cnames.structs.StructDeclaredDefined? = null
|
||||
val declaredDefined: StructDeclaredDefined? = null
|
||||
val definedUndeclared: StructDefinedUndeclared? = null
|
||||
val cnamesDefinedDeclared: cnames.structs.StructDefinedDeclared? = null
|
||||
val definedDeclared: StructDefinedDeclared? = null
|
||||
val definedDefined1: cForwardDeclarationsTwoLibs1.StructDefinedDefined? = null
|
||||
val definedDefined2: cForwardDeclarationsTwoLibs2.StructDefinedDefined? = null
|
||||
|
||||
assertEquals(1, checkDifferentTypes(undeclaredDeclared))
|
||||
assertEquals(2, checkDifferentTypes(undeclaredDefined))
|
||||
assertEquals(3, checkDifferentTypes(declaredUndeclared))
|
||||
assertEquals(4, checkDifferentTypes(declaredDeclared))
|
||||
assertEquals(5, checkDifferentTypes(declaredDefined))
|
||||
assertEquals(6, checkDifferentTypes(definedUndeclared))
|
||||
assertEquals(7, checkDifferentTypes(definedDeclared))
|
||||
assertEquals(8, checkDifferentTypes(definedDefined1))
|
||||
assertEquals(9, checkDifferentTypes(definedDefined2))
|
||||
|
||||
assertEquals(1, use2StructUndeclaredDeclared(undeclaredDeclared?.ptr))
|
||||
assertEquals(2, use2StructUndeclaredDefined(undeclaredDefined?.ptr))
|
||||
assertEquals(-3, use1StructDeclaredUndeclared(declaredUndeclared?.ptr))
|
||||
assertEquals(-4, use1StructDeclaredDeclared(declaredDeclared?.ptr))
|
||||
assertEquals(4, use2StructDeclaredDeclared(declaredDeclared?.ptr))
|
||||
assertEquals(-5, use1StructDeclaredDefined(cnamesDeclaredDefined?.ptr))
|
||||
assertEquals(5, use2StructDeclaredDefined(declaredDefined?.ptr))
|
||||
assertEquals(-6, use1StructDefinedUndeclared(definedUndeclared?.ptr))
|
||||
assertEquals(-7, use1StructDefinedDeclared(definedDeclared?.ptr))
|
||||
assertEquals(7, use2StructDefinedDeclared(cnamesDefinedDeclared?.ptr))
|
||||
assertEquals(-8, use1StructDefinedDefined(definedDefined1?.ptr))
|
||||
assertEquals(8, use2StructDefinedDefined(definedDefined2?.ptr))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright 2010-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// MODULE: cinterop
|
||||
// FILE: cglobals.def
|
||||
---
|
||||
const int g1 = 42;
|
||||
|
||||
int g2 = 17;
|
||||
|
||||
struct S {
|
||||
int x;
|
||||
} g3 = { 128 };
|
||||
|
||||
int g4[2] = { 13, 14 };
|
||||
|
||||
int g5[2][2] = { 15, 16, 17, 18 };
|
||||
|
||||
struct S* const g6 = &g3;
|
||||
|
||||
void globals_foo() {
|
||||
// Test that local vars are not treated as global ones.
|
||||
float g1;
|
||||
}
|
||||
|
||||
// Test non-compilable variable:
|
||||
typedef int MyInt;
|
||||
MyInt g7;
|
||||
#define g7 bad macro
|
||||
|
||||
// Test property name mangling:
|
||||
struct g1 {};
|
||||
struct g1_ {};
|
||||
|
||||
typedef void* voidptr;
|
||||
_Pragma("clang assume_nonnull begin")
|
||||
const voidptr g8 = 0x1, g9 = 0x2;
|
||||
_Pragma("clang assume_nonnull end")
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class, kotlin.experimental.ExperimentalNativeApi::class)
|
||||
|
||||
import kotlinx.cinterop.*
|
||||
import cglobals.*
|
||||
|
||||
fun box(): String {
|
||||
assert(g1__ == 42)
|
||||
|
||||
assert(g2 == 17)
|
||||
g2 = 42
|
||||
assert(g2 == 42)
|
||||
|
||||
assert(g3.x == 128)
|
||||
g3.x = 7
|
||||
assert(g3.x == 7)
|
||||
|
||||
assert(g4[1] == 14)
|
||||
g4[1] = 15
|
||||
assert(g4[1] == 15)
|
||||
|
||||
assert(g5[0] == 15)
|
||||
assert(g5[3] == 18)
|
||||
g5[0] = 16
|
||||
assert(g5[0] == 16)
|
||||
|
||||
assert(g6 == g3.ptr)
|
||||
|
||||
assert(g8.toLong() == 0x1L)
|
||||
assert(g9.toLong() == 0x2L)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
// FREE_CINTEROP_ARGS: -header incompleteTypes.h
|
||||
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// MODULE: cinterop
|
||||
// FILE: incompleteTypes.def
|
||||
# The def file is intentionally empty
|
||||
# `incompleteTypes.h` is meant to be included via `-header` option of cinterop tool
|
||||
|
||||
// FILE: incompleteTypes.h
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Forward declaration.
|
||||
struct S;
|
||||
extern struct S s;
|
||||
|
||||
const char* getContent(struct S* s);
|
||||
void setContent(struct S* s, const char* name);
|
||||
|
||||
union U;
|
||||
extern union U u;
|
||||
|
||||
double getDouble(union U* u);
|
||||
void setDouble(union U* u, double value);
|
||||
|
||||
// Global array of unknown size.
|
||||
extern char array[];
|
||||
|
||||
|
||||
int arrayLength();
|
||||
void setArrayValue(char* array, char value);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
// FILE: incompleteTypes.cpp
|
||||
#include <string>
|
||||
#include "incompleteTypes.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
struct S {
|
||||
std::string name;
|
||||
};
|
||||
|
||||
S s = {
|
||||
.name = "initial"
|
||||
};
|
||||
|
||||
void setContent(struct S* s, const char* name) {
|
||||
// Note that copy here is intentional: we use it as a workaround
|
||||
// for short lifetime of copy of the passed Kotlin string.
|
||||
s->name = name;
|
||||
}
|
||||
|
||||
const char* getContent(struct S* s) {
|
||||
return s->name.c_str();
|
||||
}
|
||||
|
||||
union U {
|
||||
float f;
|
||||
double d;
|
||||
};
|
||||
|
||||
void setDouble(union U* u, double value) {
|
||||
u->d = value;
|
||||
}
|
||||
|
||||
double getDouble(union U* u) {
|
||||
return u->d;
|
||||
}
|
||||
|
||||
union U u = {
|
||||
.d = 0.0
|
||||
};
|
||||
|
||||
char array[5] = { 0, 0, 0, 0, 0 };
|
||||
|
||||
void setArrayValue(char* array, char value) {
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
array[i] = value;
|
||||
}
|
||||
}
|
||||
|
||||
int arrayLength() {
|
||||
return sizeof(array) / sizeof(char);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
import incompleteTypes.*
|
||||
import kotlinx.cinterop.*
|
||||
import kotlin.test.*
|
||||
|
||||
fun box(): String {
|
||||
assertNotNull(s.ptr)
|
||||
assertNotNull(u.ptr)
|
||||
assertNotNull(array)
|
||||
|
||||
assertEquals("initial", getContent(s.ptr)?.toKString())
|
||||
setContent(s.ptr, "yo")
|
||||
val ptr = getContent(s.ptr)
|
||||
assertEquals("yo", ptr?.toKString())
|
||||
|
||||
assertEquals(0.0, getDouble(u.ptr))
|
||||
setDouble(u.ptr, Double.MIN_VALUE)
|
||||
assertEquals(Double.MIN_VALUE, getDouble(u.ptr))
|
||||
|
||||
for (i in 0 until arrayLength()) {
|
||||
assertEquals(0x0, array[i])
|
||||
}
|
||||
setArrayValue(array, 0x1)
|
||||
for (i in 0 until arrayLength()) {
|
||||
assertEquals(0x1, array[i])
|
||||
}
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// MODULE: cinterop
|
||||
// FILE: kt43265.def
|
||||
strictEnums = bcm2835FunctionSelect
|
||||
---
|
||||
enum bcm2835FunctionSelect {
|
||||
BCM2835_GPIO_FSEL_INPT = 0x00, BCM2835_GPIO_FSEL_OUTP = 0x01, BCM2835_GPIO_FSEL_ALT0 = 0x04, BCM2835_GPIO_FSEL_ALT1 = 0x05,
|
||||
BCM2835_GPIO_FSEL_ALT2 = 0x06, BCM2835_GPIO_FSEL_ALT3 = 0x07, BCM2835_GPIO_FSEL_ALT4 = 0x03, BCM2835_GPIO_FSEL_ALT5 = 0x02,
|
||||
BCM2835_GPIO_FSEL_MASK = 0x07
|
||||
};
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
|
||||
import kt43265.*
|
||||
import kotlin.test.*
|
||||
|
||||
@kotlinx.cinterop.ExperimentalForeignApi
|
||||
fun box(): String {
|
||||
assertEquals(bcm2835FunctionSelect.BCM2835_GPIO_FSEL_ALT3, bcm2835FunctionSelect.BCM2835_GPIO_FSEL_MASK)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// MODULE: cinterop
|
||||
// FILE: kt44283.def
|
||||
---
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
|
||||
typedef struct {
|
||||
int d;
|
||||
} TestStruct;
|
||||
|
||||
typedef struct {
|
||||
void (*f)(TestStruct data);
|
||||
} ThreadData;
|
||||
|
||||
void *dispatch(void *rawArg) {
|
||||
ThreadData *arg = rawArg;
|
||||
arg->f((TestStruct) {.d = 1});
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void invokeFromThread(void (*f)(TestStruct data)) {
|
||||
pthread_t thread_id;
|
||||
ThreadData *threadData = malloc(sizeof(ThreadData));
|
||||
threadData->f = f;
|
||||
pthread_create(&thread_id, NULL, dispatch, (void *) threadData);
|
||||
pthread_join(thread_id, NULL);
|
||||
}
|
||||
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlin.native.runtime.NativeRuntimeApi::class)
|
||||
|
||||
import kotlinx.cinterop.*
|
||||
import kt44283.*
|
||||
import kotlin.concurrent.AtomicInt
|
||||
import kotlin.test.*
|
||||
|
||||
val callbackCounter = AtomicInt(0)
|
||||
|
||||
@ExperimentalForeignApi
|
||||
fun box(): String {
|
||||
val func = staticCFunction<CValue<TestStruct>, Unit> {
|
||||
kotlin.native.runtime.GC.collect() // Helps to ensure that "runtime" is already initialized.
|
||||
|
||||
memScoped {
|
||||
println("Hello, Kotlin/Native! ${it.ptr.pointed.d}")
|
||||
}
|
||||
callbackCounter.incrementAndGet()
|
||||
}
|
||||
|
||||
assertEquals(0, callbackCounter.value)
|
||||
invokeFromThread(func.reinterpret())
|
||||
assertEquals(1, callbackCounter.value)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// MODULE: cinterop
|
||||
// FILE: kt51925.def
|
||||
strictEnums = E
|
||||
---
|
||||
enum E {
|
||||
X = 1, Y = 2, Z = 42
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
int d;
|
||||
} Struct;
|
||||
|
||||
// MODULE: lib(cinterop)
|
||||
// FILE: lib.kt
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
import kt51925.*
|
||||
import kotlinx.cinterop.*
|
||||
|
||||
fun bar1(e: E) = e.value
|
||||
|
||||
inline fun foo1() = bar1(E.Z)
|
||||
|
||||
fun bar2(s: Struct): Int {
|
||||
return s.d
|
||||
}
|
||||
|
||||
inline fun foo2(): Int {
|
||||
memScoped {
|
||||
val s = alloc<Struct>()
|
||||
s.d = 42
|
||||
return bar2(s)
|
||||
}
|
||||
}
|
||||
|
||||
// MODULE: main(lib)
|
||||
// FILE: main.kt
|
||||
import kotlin.test.*
|
||||
|
||||
fun box(): String {
|
||||
assertEquals(42u, foo1())
|
||||
assertEquals(42, foo2())
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// MODULE: cinterop
|
||||
// FILE: kt54284.def
|
||||
---
|
||||
#define KFILE "FILE:" __FILE__
|
||||
#define KLINE "LINE:" __LINE__
|
||||
#define KTIME "TIME:" __TIME__
|
||||
#define KDATE "DATE:" __DATE__
|
||||
#define KFILENAME "NAME:" __FILE_NAME__
|
||||
#define KBASEFILE "BASE:" __BASE_FILE__
|
||||
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
|
||||
import kotlinx.cinterop.*
|
||||
import kt54284.*
|
||||
import kotlin.test.*
|
||||
|
||||
@ExperimentalForeignApi
|
||||
fun box(): String {
|
||||
assertEquals("FILE:__FILE__", KFILE)
|
||||
assertEquals("LINE:__LINE__", KLINE)
|
||||
assertEquals("TIME:__TIME__", KTIME)
|
||||
assertEquals("DATE:__DATE__", KDATE)
|
||||
assertEquals("NAME:__FILE_NAME__", KFILENAME)
|
||||
assertEquals("BASE:__BASE_FILE__", KBASEFILE)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// MODULE: cinterop
|
||||
// FILE: kt54284_fmodules.def
|
||||
compilerOpts = -fmodules
|
||||
---
|
||||
#define KFILE "FILE:" __FILE__
|
||||
#define KLINE "LINE:" __LINE__
|
||||
#define KTIME "TIME:" __TIME__
|
||||
#define KDATE "DATE:" __DATE__
|
||||
#define KFILENAME "NAME:" __FILE_NAME__
|
||||
#define KBASEFILE "BASE:" __BASE_FILE__
|
||||
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
import kotlinx.cinterop.*
|
||||
import kt54284_fmodules.*
|
||||
import kotlin.test.*
|
||||
|
||||
@ExperimentalForeignApi
|
||||
fun box(): String {
|
||||
assertEquals("FILE:__FILE__", KFILE)
|
||||
assertEquals("LINE:__LINE__", KLINE)
|
||||
assertEquals("TIME:__TIME__", KTIME)
|
||||
assertEquals("DATE:__DATE__", KDATE)
|
||||
assertEquals("NAME:__FILE_NAME__", KFILENAME)
|
||||
assertEquals("BASE:__BASE_FILE__", KBASEFILE)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,680 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// MODULE: cinterop
|
||||
// FILE: kt57640.def
|
||||
language = Objective-C
|
||||
headers = kt57640.h
|
||||
|
||||
// FILE: kt57640.h
|
||||
#import <Foundation/NSObject.h>
|
||||
|
||||
@interface Base : NSObject
|
||||
@property (readwrite) Base* delegate;
|
||||
@end
|
||||
|
||||
@protocol Foo
|
||||
@property (readwrite) id<Foo> delegate;
|
||||
@end
|
||||
|
||||
@protocol Bar
|
||||
@property (readwrite) id<Bar> delegate;
|
||||
@end
|
||||
|
||||
@interface Derived : Base<Bar, Foo>
|
||||
// This interface does not have re-declaration of property `delegate`.
|
||||
// Return type of getter `delegate()` and param type of setter `setDelegate()` are:
|
||||
// the type of property defined in the first mentioned protocol (id<Bar>), which is incompatible with property type.
|
||||
@end
|
||||
|
||||
@interface DerivedWithPropertyOverride : Base<Bar, Foo>
|
||||
// This interface does not have re-declaration of property `delegate`.
|
||||
// Return type of getter `delegate()` and param type of setter `setDelegate()` are `DerivedWithPropertyOverride*`
|
||||
@property (readwrite) DerivedWithPropertyOverride* delegate;
|
||||
@end
|
||||
|
||||
// FILE: kt57640.m
|
||||
#import "kt57640.h"
|
||||
|
||||
@implementation Base
|
||||
@end
|
||||
|
||||
@implementation Derived
|
||||
@end
|
||||
|
||||
@implementation DerivedWithPropertyOverride
|
||||
@end
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
import kt57640.*
|
||||
import kotlin.test.*
|
||||
|
||||
class GrandDerived: Derived() {}
|
||||
class GrandDerivedWithPropertyOverride: DerivedWithPropertyOverride() {}
|
||||
|
||||
/**
|
||||
* class KotlinInterfaceDerived would cause errors, this deserves a diagnostic test
|
||||
* error: class 'KotlinInterfaceDerived' must override 'delegate' because it inherits multiple implementations for it.
|
||||
* error: 'delegate' clashes with 'delegate': return types are incompatible.
|
||||
* error: 'delegate' clashes with 'delegate': property types do not match.
|
||||
*/
|
||||
//class KotlinInterfaceDerived: Base(), FooProtocol, BarProtocol
|
||||
|
||||
fun box(): String {
|
||||
testBase()
|
||||
|
||||
testAssignmentDerivedToDerived()
|
||||
testAssignmentDerivedToBase()
|
||||
testAssignmentBaseToDerived()
|
||||
|
||||
testAssignmentDerivedWithPropertyOverrideToDerivedWithPropertyOverride()
|
||||
testAssignmentDerivedWithPropertyOverrideToBase()
|
||||
testAssignmentBaseToDerivedWithPropertyOverride()
|
||||
|
||||
testGrandDerived()
|
||||
testGrandDerivedWithPropertyOverride()
|
||||
testAssigmmentDerivedWithPropertyOverrideToGrandDerivedWithPropertyOverride()
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
private fun testBase() {
|
||||
val base = Base()
|
||||
val delegate00_Base: Base? = base.delegate
|
||||
assertEquals(null, delegate00_Base)
|
||||
val delegate01_Base: Base? = base.delegate()
|
||||
assertEquals(null, delegate01_Base)
|
||||
|
||||
base.delegate = base
|
||||
val delegate02_Base: Base? = base.delegate
|
||||
assertEquals(base, delegate02_Base)
|
||||
val delegate03_Base: Base? = base.delegate()
|
||||
assertEquals(base, delegate03_Base)
|
||||
}
|
||||
|
||||
private fun testAssignmentDerivedToDerived() {
|
||||
val derived = Derived()
|
||||
val delegate10_Base: Base? = derived.delegate
|
||||
assertEquals(null, delegate10_Base)
|
||||
val delegate11_Bar: BarProtocol? = derived.delegate()
|
||||
assertEquals(null, delegate11_Bar)
|
||||
|
||||
derived.delegate = derived
|
||||
derived.setDelegate(derived)
|
||||
|
||||
val delegate12_Base: Base? = derived.delegate
|
||||
assertTrue(delegate12_Base is Base)
|
||||
assertTrue(delegate12_Base is FooProtocol)
|
||||
assertTrue(delegate12_Base is BarProtocol)
|
||||
assertTrue(delegate12_Base is Derived)
|
||||
assertEquals(derived, delegate12_Base)
|
||||
val delegate16_Bar: BarProtocol? = derived.delegate()
|
||||
assertTrue(delegate16_Bar is Base)
|
||||
assertTrue(delegate16_Bar is FooProtocol)
|
||||
assertTrue(delegate16_Bar is BarProtocol)
|
||||
assertTrue(delegate16_Bar is Derived)
|
||||
assertEquals(derived, delegate16_Bar)
|
||||
|
||||
val delegate13_Base: Base? = (derived as Base).delegate
|
||||
assertTrue(delegate13_Base is Base)
|
||||
assertTrue(delegate13_Base is FooProtocol)
|
||||
assertTrue(delegate13_Base is BarProtocol)
|
||||
assertTrue(delegate13_Base is Derived)
|
||||
assertEquals(derived, delegate13_Base)
|
||||
val delegate17_Base: Base? = (derived as Base).delegate()
|
||||
assertTrue(delegate17_Base is Base)
|
||||
assertTrue(delegate17_Base is FooProtocol)
|
||||
assertTrue(delegate17_Base is BarProtocol)
|
||||
assertTrue(delegate17_Base is Derived)
|
||||
assertEquals(derived, delegate17_Base)
|
||||
|
||||
val delegate14_Foo: FooProtocol? = (derived as FooProtocol).delegate
|
||||
assertTrue(delegate14_Foo is Base)
|
||||
assertTrue(delegate14_Foo is FooProtocol)
|
||||
assertTrue(delegate14_Foo is BarProtocol)
|
||||
assertTrue(delegate14_Foo is Derived)
|
||||
assertEquals(derived, delegate14_Foo)
|
||||
val delegate18_Foo: FooProtocol? = (derived as FooProtocol).delegate()
|
||||
assertTrue(delegate18_Foo is Base)
|
||||
assertTrue(delegate18_Foo is FooProtocol)
|
||||
assertTrue(delegate18_Foo is BarProtocol)
|
||||
assertTrue(delegate18_Foo is Derived)
|
||||
assertEquals(derived, delegate18_Foo)
|
||||
|
||||
val delegate15_Bar: BarProtocol? = (derived as BarProtocol).delegate
|
||||
assertTrue(delegate15_Bar is Base)
|
||||
assertTrue(delegate15_Bar is FooProtocol)
|
||||
assertTrue(delegate15_Bar is BarProtocol)
|
||||
assertTrue(delegate15_Bar is Derived)
|
||||
assertEquals(derived, delegate15_Bar)
|
||||
val delegate19_Bar: BarProtocol? = (derived as BarProtocol).delegate()
|
||||
assertTrue(delegate19_Bar is Base)
|
||||
assertTrue(delegate19_Bar is FooProtocol)
|
||||
assertTrue(delegate19_Bar is BarProtocol)
|
||||
assertTrue(delegate19_Bar is Derived)
|
||||
assertEquals(derived, delegate19_Bar)
|
||||
}
|
||||
|
||||
private fun testAssignmentDerivedToBase() {
|
||||
val base = Base()
|
||||
val delegate10_Base: Base? = base.delegate
|
||||
assertEquals(null, delegate10_Base)
|
||||
val delegate11_Base: Base? = base.delegate()
|
||||
assertEquals(null, delegate11_Base)
|
||||
|
||||
base.delegate = base
|
||||
base.setDelegate(base)
|
||||
val derived = Derived()
|
||||
base.delegate = derived
|
||||
|
||||
val delegate12_Base: Base? = base.delegate
|
||||
assertTrue(delegate12_Base is Base)
|
||||
assertTrue(delegate12_Base is FooProtocol)
|
||||
assertTrue(delegate12_Base is BarProtocol)
|
||||
assertTrue(delegate12_Base is Derived)
|
||||
assertEquals(derived, delegate12_Base)
|
||||
val delegate16_Base: Base? = base.delegate()
|
||||
assertTrue(delegate16_Base is Base)
|
||||
assertTrue(delegate16_Base is FooProtocol)
|
||||
assertTrue(delegate16_Base is BarProtocol)
|
||||
assertTrue(delegate16_Base is Derived)
|
||||
assertEquals(derived, delegate16_Base)
|
||||
}
|
||||
|
||||
private fun testAssignmentBaseToDerived() {
|
||||
val derived = Derived()
|
||||
val delegate10_Base: Base? = derived.delegate
|
||||
assertEquals(null, delegate10_Base)
|
||||
val delegate11_Bar: BarProtocol? = derived.delegate()
|
||||
assertEquals(null, delegate11_Bar)
|
||||
|
||||
val base = Base()
|
||||
derived.delegate = base
|
||||
// derived.setDelegate(base) // argument type mismatch, this deserves a diagnostic test
|
||||
|
||||
val delegate12_Base: Base? = derived.delegate
|
||||
assertTrue(delegate12_Base is Base)
|
||||
assertFalse(delegate12_Base is FooProtocol)
|
||||
assertFalse(delegate12_Base is BarProtocol)
|
||||
assertFalse(delegate12_Base is Derived)
|
||||
assertEquals(base, delegate12_Base)
|
||||
val delegate16_Bar: BarProtocol? = derived.delegate()
|
||||
val delegate16_Any: Any? = delegate16_Bar
|
||||
assertTrue(delegate16_Bar is Base)
|
||||
assertTrue(delegate16_Any is Base)
|
||||
assertFalse(delegate16_Bar is FooProtocol)
|
||||
assertFalse(delegate16_Any is FooProtocol)
|
||||
// Behavior of next "is" check depends on existence of static type analysis: static analysis calculates "is" result as "true",
|
||||
// while at run-time, the type is Base, which isn't BarProtocol, and the "is" result is "false"
|
||||
// assertFalse(delegate16_Bar is BarProtocol)
|
||||
assertFalse(delegate16_Any is BarProtocol) // actual type is Base, which isn't BarProtocol
|
||||
assertFalse(delegate16_Bar is Derived)
|
||||
assertFalse(delegate16_Any is Derived)
|
||||
assertEquals(base, delegate16_Bar)
|
||||
assertEquals(base, delegate16_Any)
|
||||
|
||||
val delegate13_Base: Base? = (derived as Base).delegate
|
||||
assertTrue(delegate13_Base is Base)
|
||||
assertFalse(delegate13_Base is FooProtocol)
|
||||
assertFalse(delegate13_Base is BarProtocol)
|
||||
assertFalse(delegate13_Base is Derived)
|
||||
assertEquals(base, delegate13_Base)
|
||||
val delegate17_Base: Base? = (derived as Base).delegate()
|
||||
assertTrue(delegate17_Base is Base)
|
||||
assertFalse(delegate17_Base is FooProtocol)
|
||||
assertFalse(delegate17_Base is BarProtocol)
|
||||
assertFalse(delegate17_Base is Derived)
|
||||
assertEquals(base, delegate17_Base)
|
||||
|
||||
val delegate14_Foo: FooProtocol? = (derived as FooProtocol).delegate
|
||||
val delegate14_Any: Any? = delegate14_Foo
|
||||
assertTrue(delegate14_Foo is Base)
|
||||
assertTrue(delegate14_Any is Base)
|
||||
// Behavior of next "is" check depends on existence of static type analysis: static analysis calculates "is" result as "true",
|
||||
// while at run-time, the type is Base, which isn't FooProtocol, and the "is" result is "false"
|
||||
// assertFalse(delegate14_Foo is FooProtocol)
|
||||
assertFalse(delegate14_Any is FooProtocol) // actual type is Base, which isn't FooProtocol
|
||||
assertFalse(delegate14_Foo is BarProtocol)
|
||||
assertFalse(delegate14_Any is BarProtocol)
|
||||
assertFalse(delegate14_Foo is Derived)
|
||||
assertEquals(base, delegate14_Foo as Base)
|
||||
assertEquals(base, delegate14_Any as Base)
|
||||
|
||||
val delegate18_Foo: FooProtocol? = (derived as FooProtocol).delegate()
|
||||
val delegate18_Any: Any? = delegate18_Foo
|
||||
assertTrue(delegate18_Foo is Base)
|
||||
assertTrue(delegate18_Any is Base)
|
||||
// Behavior of next "is" check depends on existence of static type analysis: static analysis calculates "is" result as "true",
|
||||
// while at run-time, the type is Base, which isn't FooProtocol, and the "is" result is "false"
|
||||
// assertFalse(delegate18_Foo is FooProtocol)
|
||||
assertFalse(delegate18_Any is FooProtocol) // actual type is Base, which isn't FooProtocol
|
||||
assertFalse(delegate18_Foo is BarProtocol)
|
||||
assertFalse(delegate18_Any is BarProtocol)
|
||||
assertFalse(delegate18_Foo is Derived)
|
||||
assertFalse(delegate18_Any is Derived)
|
||||
assertEquals(base, delegate18_Foo)
|
||||
assertEquals(base, delegate18_Any)
|
||||
|
||||
val delegate15_Bar: BarProtocol? = (derived as BarProtocol).delegate
|
||||
val delegate15_Any: Any? = delegate15_Bar
|
||||
assertTrue(delegate15_Bar is Base)
|
||||
assertTrue(delegate15_Any is Base)
|
||||
assertFalse(delegate15_Bar is FooProtocol)
|
||||
assertFalse(delegate15_Any is FooProtocol)
|
||||
// Behavior of next "is" check depends on existence of static type analysis: static analysis calculates "is" result as "true",
|
||||
// while at run-time, the type is Base, which isn't BarProtocol, and the "is" result is "false"
|
||||
// assertFalse(delegate15_Bar is BarProtocol)
|
||||
assertFalse(delegate15_Any is BarProtocol) // actual type is Base, which isn't BarProtocol
|
||||
assertFalse(delegate15_Bar is Derived)
|
||||
assertFalse(delegate15_Any is Derived)
|
||||
assertEquals(base, delegate15_Bar as Base)
|
||||
assertEquals(base, delegate15_Any as Base)
|
||||
|
||||
val delegate19_Bar: BarProtocol? = (derived as BarProtocol).delegate()
|
||||
val delegate19_Any: Any? = delegate19_Bar
|
||||
assertTrue(delegate19_Bar is Base)
|
||||
assertTrue(delegate19_Any is Base)
|
||||
assertFalse(delegate19_Bar is FooProtocol)
|
||||
assertFalse(delegate19_Any is FooProtocol)
|
||||
// Behavior of next "is" check depends on existence of static type analysis: static analysis calculates "is" result as "true",
|
||||
// while at run-time, the type is Base, which isn't BarProtocol, and the "is" result is "false"
|
||||
// assertFalse(delegate19_Bar is BarProtocol)
|
||||
assertFalse(delegate19_Any is BarProtocol) // actual type is Base, which isn't BarProtocol
|
||||
assertFalse(delegate19_Bar is Derived)
|
||||
assertFalse(delegate19_Any is Derived)
|
||||
assertEquals(base, delegate19_Bar)
|
||||
assertEquals(base, delegate19_Any)
|
||||
}
|
||||
|
||||
private fun testAssignmentDerivedWithPropertyOverrideToDerivedWithPropertyOverride() {
|
||||
val derived = DerivedWithPropertyOverride()
|
||||
// WARNING: static type of backing field in CInterop KLib is `Base?`, but not expected `DerivedWithPropertyOverride?`. Comments below are related
|
||||
val delegate10_Base: Base? = derived.delegate
|
||||
assertEquals(null, delegate10_Base)
|
||||
val delegate11_Bar: BarProtocol? = derived.delegate()
|
||||
assertEquals(null, delegate11_Bar)
|
||||
|
||||
derived.delegate = derived
|
||||
derived.setDelegate(derived)
|
||||
|
||||
val delegate12_Base: Base? = derived.delegate // static type is Base?, not DerivedWithPropertyOverride?, this deserves a diagnostic test
|
||||
assertTrue(delegate12_Base is Base)
|
||||
assertTrue(delegate12_Base is FooProtocol)
|
||||
assertTrue(delegate12_Base is BarProtocol)
|
||||
assertTrue(delegate12_Base is DerivedWithPropertyOverride)
|
||||
assertEquals(derived, delegate12_Base)
|
||||
val delegate19_DerivedWithPropertyOverride: DerivedWithPropertyOverride? = derived.delegate()
|
||||
assertTrue(delegate19_DerivedWithPropertyOverride is Base)
|
||||
assertTrue(delegate19_DerivedWithPropertyOverride is FooProtocol)
|
||||
assertTrue(delegate19_DerivedWithPropertyOverride is BarProtocol)
|
||||
assertTrue(delegate19_DerivedWithPropertyOverride is DerivedWithPropertyOverride)
|
||||
assertEquals(derived, delegate19_DerivedWithPropertyOverride)
|
||||
|
||||
val delegate13_Base: Base? = (derived as Base).delegate
|
||||
assertTrue(delegate13_Base is Base)
|
||||
assertTrue(delegate13_Base is FooProtocol)
|
||||
assertTrue(delegate13_Base is BarProtocol)
|
||||
assertTrue(delegate13_Base is DerivedWithPropertyOverride)
|
||||
assertEquals(derived, delegate13_Base)
|
||||
val delegate17_Base: Base? = (derived as Base).delegate() // static type is Base?, not DerivedWithPropertyOverride?, this deserves a diagnostic test
|
||||
assertTrue(delegate17_Base is Base)
|
||||
assertTrue(delegate17_Base is FooProtocol)
|
||||
assertTrue(delegate17_Base is BarProtocol)
|
||||
assertTrue(delegate17_Base is DerivedWithPropertyOverride)
|
||||
assertEquals(derived, delegate17_Base)
|
||||
|
||||
val delegate14_Foo: FooProtocol? = (derived as FooProtocol).delegate
|
||||
assertTrue(delegate14_Foo is Base)
|
||||
assertTrue(delegate14_Foo is FooProtocol)
|
||||
assertTrue(delegate14_Foo is BarProtocol)
|
||||
assertTrue(delegate14_Foo is DerivedWithPropertyOverride)
|
||||
assertEquals(derived, delegate14_Foo)
|
||||
val delegate18_Foo: FooProtocol? = (derived as FooProtocol).delegate() // static type is FooProtocol?, not DerivedWithPropertyOverride?, this deserves a diagnostic test
|
||||
assertTrue(delegate18_Foo is Base)
|
||||
assertTrue(delegate18_Foo is FooProtocol)
|
||||
assertTrue(delegate18_Foo is BarProtocol)
|
||||
assertTrue(delegate18_Foo is DerivedWithPropertyOverride)
|
||||
assertEquals(derived, delegate18_Foo)
|
||||
|
||||
val delegate15_Bar: BarProtocol? = (derived as BarProtocol).delegate
|
||||
assertTrue(delegate15_Bar is Base)
|
||||
assertTrue(delegate15_Bar is FooProtocol)
|
||||
assertTrue(delegate15_Bar is BarProtocol)
|
||||
assertTrue(delegate15_Bar is DerivedWithPropertyOverride)
|
||||
assertEquals(derived, delegate15_Bar)
|
||||
val delegate19_Bar: BarProtocol? = (derived as BarProtocol).delegate() // static type is BarProtocol?, not DerivedWithPropertyOverride?, this deserves a diagnostic test
|
||||
assertTrue(delegate19_Bar is Base)
|
||||
assertTrue(delegate19_Bar is FooProtocol)
|
||||
assertTrue(delegate19_Bar is BarProtocol)
|
||||
assertTrue(delegate19_Bar is DerivedWithPropertyOverride)
|
||||
assertEquals(derived, delegate19_Bar)
|
||||
}
|
||||
|
||||
private fun testAssignmentDerivedWithPropertyOverrideToBase() {
|
||||
val base = Base()
|
||||
val delegate10_Base: Base? = base.delegate
|
||||
assertEquals(null, delegate10_Base)
|
||||
val delegate11_Base: Base? = base.delegate()
|
||||
assertEquals(null, delegate11_Base)
|
||||
|
||||
val derived = DerivedWithPropertyOverride()
|
||||
base.delegate = derived
|
||||
base.setDelegate(derived)
|
||||
|
||||
val delegate12_Base: Base? = base.delegate
|
||||
assertTrue(delegate12_Base is Base)
|
||||
assertTrue(delegate12_Base is FooProtocol)
|
||||
assertTrue(delegate12_Base is BarProtocol)
|
||||
assertTrue(delegate12_Base is DerivedWithPropertyOverride)
|
||||
assertEquals(derived, delegate12_Base)
|
||||
val delegate19_Base: Base? = base.delegate()
|
||||
assertTrue(delegate19_Base is Base)
|
||||
assertTrue(delegate19_Base is FooProtocol)
|
||||
assertTrue(delegate19_Base is BarProtocol)
|
||||
assertTrue(delegate19_Base is DerivedWithPropertyOverride)
|
||||
assertEquals(derived, delegate19_Base)
|
||||
}
|
||||
|
||||
private fun testAssignmentBaseToDerivedWithPropertyOverride() {
|
||||
val derived = DerivedWithPropertyOverride()
|
||||
// WARNING: static type of backing field in CInterop KLib is `Base?`, but not expected `DerivedWithPropertyOverride?`. Comments below are related
|
||||
val delegate10_Base: Base? = derived.delegate
|
||||
assertEquals(null, delegate10_Base)
|
||||
val delegate11_Bar: BarProtocol? = derived.delegate()
|
||||
assertEquals(null, delegate11_Bar)
|
||||
|
||||
val base = Base()
|
||||
derived.delegate = base
|
||||
// derived.setDelegate(base) // argument type mismatch: actual type is 'library.Base', but 'library.DerivedWithPropertyOverride?' was expected, this deserves a diagnostic test
|
||||
|
||||
val delegate12_Base: Base? = derived.delegate // static type is Base?, not DerivedWithPropertyOverride?, this deserves a diagnostic test
|
||||
assertTrue(delegate12_Base is Base)
|
||||
assertFalse(delegate12_Base is FooProtocol)
|
||||
assertFalse(delegate12_Base is BarProtocol)
|
||||
assertFalse(delegate12_Base is DerivedWithPropertyOverride)
|
||||
assertEquals(base, delegate12_Base)
|
||||
val delegate19_DerivedWithPropertyOverride: DerivedWithPropertyOverride? = derived.delegate()
|
||||
assertTrue(delegate19_DerivedWithPropertyOverride is Base)
|
||||
assertTrue(delegate19_DerivedWithPropertyOverride is FooProtocol)
|
||||
assertTrue(delegate19_DerivedWithPropertyOverride is BarProtocol)
|
||||
assertTrue(delegate19_DerivedWithPropertyOverride is DerivedWithPropertyOverride)
|
||||
assertEquals(base, delegate19_DerivedWithPropertyOverride)
|
||||
|
||||
val delegate13_Base: Base? = (derived as Base).delegate
|
||||
assertTrue(delegate13_Base is Base)
|
||||
assertFalse(delegate13_Base is FooProtocol)
|
||||
assertFalse(delegate13_Base is BarProtocol)
|
||||
assertFalse(delegate13_Base is DerivedWithPropertyOverride)
|
||||
assertEquals(base, delegate13_Base)
|
||||
val delegate17_Base: Base? = (derived as Base).delegate() // static type is Base?, not DerivedWithPropertyOverride?, this deserves a diagnostic test
|
||||
assertTrue(delegate17_Base is Base)
|
||||
assertFalse(delegate17_Base is FooProtocol)
|
||||
assertFalse(delegate17_Base is BarProtocol)
|
||||
assertFalse(delegate17_Base is DerivedWithPropertyOverride)
|
||||
assertEquals(base, delegate17_Base)
|
||||
|
||||
val delegate14_Foo: FooProtocol? = (derived as FooProtocol).delegate
|
||||
assertTrue(delegate14_Foo is Base)
|
||||
// Behavior of next "is" check depends on existence of static type analysis: static analysis calculates "is" result as "true",
|
||||
// while at run-time, the type is Base, which isn't FooProtocol, and the "is" result is "false"
|
||||
// assertFalse(delegate14_Foo is FooProtocol)
|
||||
assertFalse(delegate14_Foo is BarProtocol)
|
||||
assertFalse(delegate14_Foo is DerivedWithPropertyOverride)
|
||||
assertEquals(base, delegate14_Foo)
|
||||
val delegate18_Foo: FooProtocol? = (derived as FooProtocol).delegate() // static type is FooProtocol?, not DerivedWithPropertyOverride?, this deserves a diagnostic test
|
||||
assertTrue(delegate18_Foo is Base)
|
||||
// Behavior of next "is" check depends on existence of static type analysis: static analysis calculates "is" result as "true",
|
||||
// while at run-time, the type is Base, which isn't FooProtocol, and the "is" result is "false"
|
||||
// assertFalse(delegate18_Foo is FooProtocol)
|
||||
assertFalse(delegate18_Foo is BarProtocol)
|
||||
assertFalse(delegate18_Foo is DerivedWithPropertyOverride)
|
||||
assertEquals(base, delegate18_Foo)
|
||||
|
||||
val delegate15_Bar: BarProtocol? = (derived as BarProtocol).delegate
|
||||
assertTrue(delegate15_Bar is Base)
|
||||
assertFalse(delegate15_Bar is FooProtocol)
|
||||
// Behavior of next "is" check depends on existence of static type analysis: static analysis calculates "is" result as "true",
|
||||
// while at run-time, the type is Base, which isn't BarProtocol, and the "is" result is "false"
|
||||
// assertFalse(delegate15_Bar is BarProtocol)
|
||||
assertFalse(delegate15_Bar is DerivedWithPropertyOverride)
|
||||
assertEquals(base, delegate15_Bar)
|
||||
val delegate19_Bar: BarProtocol? = (derived as BarProtocol).delegate() // static type is BarProtocol?, not DerivedWithPropertyOverride?, this deserves a diagnostic test
|
||||
assertTrue(delegate19_Bar is Base)
|
||||
assertFalse(delegate19_Bar is FooProtocol)
|
||||
// Behavior of next "is" check depends on existence of static type analysis: static analysis calculates "is" result as "true",
|
||||
// while at run-time, the type is Base, which isn't BarProtocol, and the "is" result is "false"
|
||||
// assertFalse(delegate19_Bar is BarProtocol)
|
||||
assertFalse(delegate19_Bar is DerivedWithPropertyOverride)
|
||||
assertEquals(base, delegate19_Bar)
|
||||
}
|
||||
|
||||
private fun testGrandDerived() {
|
||||
val grandDerived = GrandDerived()
|
||||
val delegate10_Base: Base? = grandDerived.delegate
|
||||
assertEquals(null, delegate10_Base)
|
||||
val delegate11_Bar: BarProtocol? = grandDerived.delegate()
|
||||
assertEquals(null, delegate11_Bar)
|
||||
|
||||
grandDerived.delegate = Base()
|
||||
// grandDerived.setDelegate(Base()) // argument type mismatch: actual type is 'library.Base', but 'library.BarProtocol?' was expected, this deserves a diagnostic test
|
||||
grandDerived.delegate = Derived()
|
||||
grandDerived.setDelegate(Derived())
|
||||
grandDerived.delegate = grandDerived
|
||||
grandDerived.setDelegate(grandDerived)
|
||||
|
||||
val delegate12_Base: Base? = grandDerived.delegate
|
||||
assertTrue(delegate12_Base is Base)
|
||||
assertTrue(delegate12_Base is FooProtocol)
|
||||
assertTrue(delegate12_Base is BarProtocol)
|
||||
assertTrue(delegate12_Base is Derived)
|
||||
assertTrue(delegate12_Base is GrandDerived)
|
||||
assertEquals(grandDerived, delegate12_Base)
|
||||
val delegate21_Bar: BarProtocol? = grandDerived.delegate()
|
||||
assertTrue(delegate21_Bar is Base)
|
||||
assertTrue(delegate21_Bar is FooProtocol)
|
||||
assertTrue(delegate21_Bar is BarProtocol)
|
||||
assertTrue(delegate21_Bar is Derived)
|
||||
assertTrue(delegate21_Bar is GrandDerived)
|
||||
assertEquals(grandDerived, delegate21_Bar)
|
||||
|
||||
val delegate13_Base: Base? = (grandDerived as Base).delegate
|
||||
assertTrue(delegate13_Base is Base)
|
||||
assertTrue(delegate13_Base is FooProtocol)
|
||||
assertTrue(delegate13_Base is BarProtocol)
|
||||
assertTrue(delegate13_Base is Derived)
|
||||
assertTrue(delegate13_Base is GrandDerived)
|
||||
assertEquals(grandDerived, delegate13_Base)
|
||||
val delegate17_Base: Base? = (grandDerived as Base).delegate()
|
||||
assertTrue(delegate17_Base is Base)
|
||||
assertTrue(delegate17_Base is FooProtocol)
|
||||
assertTrue(delegate17_Base is BarProtocol)
|
||||
assertTrue(delegate17_Base is Derived)
|
||||
assertTrue(delegate17_Base is GrandDerived)
|
||||
assertEquals(grandDerived, delegate17_Base)
|
||||
|
||||
val delegate14_Foo: FooProtocol? = (grandDerived as FooProtocol).delegate
|
||||
assertTrue(delegate14_Foo is Base)
|
||||
assertTrue(delegate14_Foo is FooProtocol)
|
||||
assertTrue(delegate14_Foo is BarProtocol)
|
||||
assertTrue(delegate14_Foo is Derived)
|
||||
assertTrue(delegate14_Foo is GrandDerived)
|
||||
assertEquals(grandDerived, delegate14_Foo)
|
||||
val delegate18_Foo: FooProtocol? = (grandDerived as FooProtocol).delegate()
|
||||
assertTrue(delegate18_Foo is Base)
|
||||
assertTrue(delegate18_Foo is FooProtocol)
|
||||
assertTrue(delegate18_Foo is BarProtocol)
|
||||
assertTrue(delegate18_Foo is Derived)
|
||||
assertTrue(delegate18_Foo is GrandDerived)
|
||||
assertEquals(grandDerived, delegate18_Foo)
|
||||
|
||||
val delegate15_Bar: BarProtocol? = (grandDerived as BarProtocol).delegate
|
||||
assertTrue(delegate15_Bar is Base)
|
||||
assertTrue(delegate15_Bar is FooProtocol)
|
||||
assertTrue(delegate15_Bar is BarProtocol)
|
||||
assertTrue(delegate15_Bar is Derived)
|
||||
assertTrue(delegate15_Bar is GrandDerived)
|
||||
assertEquals(grandDerived, delegate15_Bar)
|
||||
val delegate19_Bar: BarProtocol? = (grandDerived as BarProtocol).delegate()
|
||||
assertTrue(delegate19_Bar is Base)
|
||||
assertTrue(delegate19_Bar is FooProtocol)
|
||||
assertTrue(delegate19_Bar is BarProtocol)
|
||||
assertTrue(delegate19_Bar is Derived)
|
||||
assertTrue(delegate19_Bar is GrandDerived)
|
||||
assertEquals(grandDerived, delegate19_Bar)
|
||||
|
||||
val delegate16_Base: Base? = (grandDerived as Derived).delegate
|
||||
assertTrue(delegate16_Base is Base)
|
||||
assertTrue(delegate16_Base is FooProtocol)
|
||||
assertTrue(delegate16_Base is BarProtocol)
|
||||
assertTrue(delegate16_Base is Derived)
|
||||
assertTrue(delegate16_Base is GrandDerived)
|
||||
assertEquals(grandDerived, delegate16_Base)
|
||||
val delegate20_Bar: BarProtocol? = (grandDerived as Derived).delegate()
|
||||
assertTrue(delegate20_Bar is Base)
|
||||
assertTrue(delegate20_Bar is FooProtocol)
|
||||
assertTrue(delegate20_Bar is BarProtocol)
|
||||
assertTrue(delegate20_Bar is Derived)
|
||||
assertTrue(delegate20_Bar is GrandDerived)
|
||||
assertEquals(grandDerived, delegate20_Bar)
|
||||
}
|
||||
|
||||
private fun testGrandDerivedWithPropertyOverride() {
|
||||
val grandDerived = GrandDerivedWithPropertyOverride()
|
||||
val delegate10_Base: Base? = grandDerived.delegate
|
||||
assertEquals(null, delegate10_Base)
|
||||
val delegate11_Bar: BarProtocol? = grandDerived.delegate()
|
||||
assertEquals(null, delegate11_Bar)
|
||||
|
||||
grandDerived.delegate = Base()
|
||||
// grandDerived.setDelegate(Base()) // argument type mismatch: actual type is 'library.Base', but 'library.DerivedWithPropertyOverride?' was expected, this deserves a diagnostic test
|
||||
grandDerived.delegate = Derived()
|
||||
// grandDerived.setDelegate(Derived()) // argument type mismatch: actual type is 'library.Derived', but 'library.DerivedWithPropertyOverride?' was expected, this deserves a diagnostic test
|
||||
grandDerived.delegate = DerivedWithPropertyOverride()
|
||||
grandDerived.setDelegate(DerivedWithPropertyOverride())
|
||||
grandDerived.delegate = grandDerived
|
||||
grandDerived.setDelegate(grandDerived)
|
||||
|
||||
val delegate12_Base: Base? = grandDerived.delegate
|
||||
assertTrue(delegate12_Base is Base)
|
||||
assertTrue(delegate12_Base is FooProtocol)
|
||||
assertTrue(delegate12_Base is BarProtocol)
|
||||
assertTrue(delegate12_Base is DerivedWithPropertyOverride)
|
||||
assertTrue(delegate12_Base is GrandDerivedWithPropertyOverride)
|
||||
assertEquals(grandDerived, delegate12_Base)
|
||||
|
||||
val delegate13_Base: Base? = (grandDerived as Base).delegate
|
||||
assertTrue(delegate13_Base is Base)
|
||||
assertTrue(delegate13_Base is FooProtocol)
|
||||
assertTrue(delegate13_Base is BarProtocol)
|
||||
assertTrue(delegate13_Base is DerivedWithPropertyOverride)
|
||||
assertTrue(delegate13_Base is GrandDerivedWithPropertyOverride)
|
||||
assertEquals(grandDerived, delegate13_Base)
|
||||
|
||||
val delegate14_Foo: FooProtocol? = (grandDerived as FooProtocol).delegate
|
||||
assertTrue(delegate14_Foo is Base)
|
||||
assertTrue(delegate14_Foo is FooProtocol)
|
||||
assertTrue(delegate14_Foo is BarProtocol)
|
||||
assertTrue(delegate14_Foo is DerivedWithPropertyOverride)
|
||||
assertTrue(delegate14_Foo is GrandDerivedWithPropertyOverride)
|
||||
assertEquals(grandDerived, delegate14_Foo)
|
||||
|
||||
val delegate15_Bar: BarProtocol? = (grandDerived as BarProtocol).delegate
|
||||
assertTrue(delegate15_Bar is Base)
|
||||
assertTrue(delegate15_Bar is FooProtocol)
|
||||
assertTrue(delegate15_Bar is BarProtocol)
|
||||
assertTrue(delegate15_Bar is DerivedWithPropertyOverride)
|
||||
assertTrue(delegate15_Bar is GrandDerivedWithPropertyOverride)
|
||||
assertEquals(grandDerived, delegate15_Bar)
|
||||
|
||||
val delegate16_DerivedWithPropertyOverride: DerivedWithPropertyOverride? = grandDerived.delegate()
|
||||
assertTrue(delegate16_DerivedWithPropertyOverride is Base)
|
||||
assertTrue(delegate16_DerivedWithPropertyOverride is FooProtocol)
|
||||
assertTrue(delegate16_DerivedWithPropertyOverride is BarProtocol)
|
||||
assertTrue(delegate16_DerivedWithPropertyOverride is DerivedWithPropertyOverride)
|
||||
assertTrue(delegate16_DerivedWithPropertyOverride is GrandDerivedWithPropertyOverride)
|
||||
assertEquals(grandDerived, delegate16_DerivedWithPropertyOverride)
|
||||
|
||||
val delegate17_Base: Base? = (grandDerived as Base).delegate()
|
||||
assertTrue(delegate17_Base is Base)
|
||||
assertTrue(delegate17_Base is FooProtocol)
|
||||
assertTrue(delegate17_Base is BarProtocol)
|
||||
assertTrue(delegate17_Base is DerivedWithPropertyOverride)
|
||||
assertTrue(delegate17_Base is GrandDerivedWithPropertyOverride)
|
||||
assertEquals(grandDerived, delegate17_Base)
|
||||
|
||||
val delegate18_FooProtocol: FooProtocol? = (grandDerived as FooProtocol).delegate()
|
||||
assertTrue(delegate18_FooProtocol is Base)
|
||||
assertTrue(delegate18_FooProtocol is FooProtocol)
|
||||
assertTrue(delegate18_FooProtocol is BarProtocol)
|
||||
assertTrue(delegate18_FooProtocol is DerivedWithPropertyOverride)
|
||||
assertTrue(delegate18_FooProtocol is GrandDerivedWithPropertyOverride)
|
||||
assertEquals(grandDerived, delegate18_FooProtocol)
|
||||
|
||||
val delegate19_BarProtocol: BarProtocol? = (grandDerived as BarProtocol).delegate()
|
||||
assertTrue(delegate19_BarProtocol is Base)
|
||||
assertTrue(delegate19_BarProtocol is FooProtocol)
|
||||
assertTrue(delegate19_BarProtocol is BarProtocol)
|
||||
assertTrue(delegate19_BarProtocol is DerivedWithPropertyOverride)
|
||||
assertTrue(delegate19_BarProtocol is GrandDerivedWithPropertyOverride)
|
||||
assertEquals(grandDerived, delegate19_BarProtocol)
|
||||
|
||||
val delegate20_DerivedWithPropertyOverride: DerivedWithPropertyOverride? = (grandDerived as DerivedWithPropertyOverride).delegate()
|
||||
assertTrue(delegate20_DerivedWithPropertyOverride is Base)
|
||||
assertTrue(delegate20_DerivedWithPropertyOverride is FooProtocol)
|
||||
assertTrue(delegate20_DerivedWithPropertyOverride is BarProtocol)
|
||||
assertTrue(delegate20_DerivedWithPropertyOverride is DerivedWithPropertyOverride)
|
||||
assertTrue(delegate20_DerivedWithPropertyOverride is GrandDerivedWithPropertyOverride)
|
||||
assertEquals(grandDerived, delegate20_DerivedWithPropertyOverride)
|
||||
}
|
||||
|
||||
private fun testAssigmmentDerivedWithPropertyOverrideToGrandDerivedWithPropertyOverride() {
|
||||
val grandDerived = GrandDerivedWithPropertyOverride()
|
||||
val delegate10_Base: Base? = grandDerived.delegate
|
||||
assertEquals(null, delegate10_Base)
|
||||
val delegate11_Bar: BarProtocol? = grandDerived.delegate()
|
||||
assertEquals(null, delegate11_Bar)
|
||||
|
||||
val derived = DerivedWithPropertyOverride()
|
||||
grandDerived.delegate = derived
|
||||
grandDerived.setDelegate(derived) // argument type mismatch: actual type is 'library.Base', but 'library.DerivedWithPropertyOverride?' was expected, this deserves a diagnostic test
|
||||
|
||||
val delegate12_Base: Base? = grandDerived.delegate
|
||||
assertTrue(delegate12_Base is Base)
|
||||
assertTrue(delegate12_Base is FooProtocol)
|
||||
assertTrue(delegate12_Base is BarProtocol)
|
||||
assertTrue(delegate12_Base is DerivedWithPropertyOverride)
|
||||
assertFalse(delegate12_Base is GrandDerivedWithPropertyOverride)
|
||||
assertEquals(derived, delegate12_Base)
|
||||
|
||||
val delegate13_Base: Base? = (grandDerived as Base).delegate
|
||||
assertTrue(delegate13_Base is Base)
|
||||
assertTrue(delegate13_Base is FooProtocol)
|
||||
assertTrue(delegate13_Base is BarProtocol)
|
||||
assertTrue(delegate13_Base is DerivedWithPropertyOverride)
|
||||
assertFalse(delegate13_Base is GrandDerivedWithPropertyOverride)
|
||||
assertEquals(derived, delegate13_Base)
|
||||
|
||||
val delegate14_Foo: FooProtocol? = (grandDerived as FooProtocol).delegate
|
||||
assertTrue(delegate14_Foo is Base)
|
||||
assertTrue(delegate14_Foo is FooProtocol)
|
||||
assertTrue(delegate14_Foo is BarProtocol)
|
||||
assertTrue(delegate14_Foo is DerivedWithPropertyOverride)
|
||||
assertFalse(delegate14_Foo is GrandDerivedWithPropertyOverride)
|
||||
assertEquals(derived, delegate14_Foo)
|
||||
|
||||
val delegate15_Bar: BarProtocol? = (grandDerived as BarProtocol).delegate
|
||||
assertTrue(delegate15_Bar is Base)
|
||||
assertTrue(delegate15_Bar is FooProtocol)
|
||||
assertTrue(delegate15_Bar is BarProtocol)
|
||||
assertTrue(delegate15_Bar is DerivedWithPropertyOverride)
|
||||
assertFalse(delegate15_Bar is GrandDerivedWithPropertyOverride)
|
||||
assertEquals(derived, delegate15_Bar)
|
||||
|
||||
val delegate16_DerivedWithPropertyOverride: DerivedWithPropertyOverride? = (grandDerived as DerivedWithPropertyOverride).delegate()
|
||||
assertTrue(delegate16_DerivedWithPropertyOverride is Base)
|
||||
assertTrue(delegate16_DerivedWithPropertyOverride is FooProtocol)
|
||||
assertTrue(delegate16_DerivedWithPropertyOverride is BarProtocol)
|
||||
assertTrue(delegate16_DerivedWithPropertyOverride is DerivedWithPropertyOverride)
|
||||
assertFalse(delegate16_DerivedWithPropertyOverride is GrandDerivedWithPropertyOverride)
|
||||
assertEquals(derived, delegate16_DerivedWithPropertyOverride)
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// DISABLE_NATIVE: isAppleTarget=false
|
||||
// There is no GameController on watchOS.
|
||||
// DISABLE_NATIVE: targetFamily=WATCHOS
|
||||
// MODULE: cinterop
|
||||
// FILE: kt59167.def
|
||||
language=Objective-C
|
||||
---
|
||||
#import <GameController/GCDevice.h>
|
||||
|
||||
// We only need to touch the problematic header to trigger the problem,
|
||||
// so actual code does not matter.
|
||||
id<GCDevice> dummy() {
|
||||
return nil;
|
||||
}
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
import kotlin.test.*
|
||||
import kt59167.*
|
||||
|
||||
fun box(): String {
|
||||
assertNull(dummy())
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// MODULE: cinterop_kt63048
|
||||
// FILE: kt63048.def
|
||||
language = Objective-C
|
||||
headers = kt63048.h
|
||||
|
||||
// FILE: kt63048.h
|
||||
#import "Foundation/NSString.h"
|
||||
#import "Foundation/NSObject.h"
|
||||
|
||||
@interface WithClassProperty : NSObject
|
||||
-(instancetype) init;
|
||||
@property (class, readonly, copy) NSString * stringProperty;
|
||||
@end
|
||||
|
||||
|
||||
// FILE: kt63048.m
|
||||
#import "kt63048.h"
|
||||
|
||||
@implementation WithClassProperty : NSObject
|
||||
-(instancetype) init {}
|
||||
+ (NSString *) stringProperty { return @"153"; }
|
||||
@end
|
||||
|
||||
|
||||
// MODULE: main(cinterop_kt63048)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class, kotlin.experimental.ExperimentalObjCName::class)
|
||||
|
||||
import kt63048.*
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@ObjCName("KotlinImplWithCompanionPropertyOverride")
|
||||
class Impl : WithClassProperty() {
|
||||
companion object : WithClassPropertyMeta() {
|
||||
override fun stringProperty(): String? = "42"
|
||||
}
|
||||
}
|
||||
|
||||
@ObjCName("KotlinImplWithoutCompanionPropertyOverride")
|
||||
class ImplWithoutOverride : WithClassProperty() {
|
||||
companion object : WithClassPropertyMeta() {
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
assertEquals("42", Impl.stringProperty())
|
||||
assertEquals("153", ImplWithoutOverride.stringProperty())
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// MODULE: cinterop
|
||||
// FILE: kt63049.def
|
||||
depends = Foundation
|
||||
language = Objective-C
|
||||
headers = kt63049.h
|
||||
|
||||
// FILE: kt63049.h
|
||||
#import "Foundation/NSObject.h"
|
||||
@interface KT63049 : NSObject
|
||||
@end
|
||||
|
||||
// FILE: kt63049.m
|
||||
#import "kt63049.h"
|
||||
@implementation KT63049 : NSObject
|
||||
@end
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class, kotlin.experimental.ExperimentalObjCName::class)
|
||||
|
||||
import kt63049.*
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class Impl : KT63049() {
|
||||
companion object : KT63049Meta() {
|
||||
fun stringProperty(): String? = "OK"
|
||||
}
|
||||
}
|
||||
|
||||
fun box() = Impl.stringProperty()
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// MODULE: lib1
|
||||
// FILE: lib1.def
|
||||
language=Objective-C
|
||||
headers=lib1.h
|
||||
|
||||
// FILE: lib1.h
|
||||
@class Foo;
|
||||
@protocol Bar;
|
||||
struct Baz;
|
||||
|
||||
// MODULE: lib2(lib1)
|
||||
// FILE: lib2.def
|
||||
language=Objective-C
|
||||
headers=lib2.h
|
||||
|
||||
// FILE: lib2.h
|
||||
#import "../lib1/lib1.h"
|
||||
|
||||
Foo* createFoo() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
id<Bar> createBar() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct Baz* createBaz() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// MODULE: main(lib1,lib2)
|
||||
// FILE: main.kt
|
||||
import kotlinx.cinterop.CPointer
|
||||
import lib1.*
|
||||
import lib2.*
|
||||
import cnames.structs.Baz
|
||||
import objcnames.classes.Foo
|
||||
import objcnames.protocols.BarProtocol
|
||||
|
||||
@OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
fun box(): String {
|
||||
val foo: Foo? = createFoo()
|
||||
if (foo !== null) return "FAIL 1"
|
||||
|
||||
val bar: BarProtocol? = createBar()
|
||||
if (bar !== null) return "FAIL 2"
|
||||
|
||||
val baz: CPointer<Baz>? = createBaz()
|
||||
if (baz !== null) return "FAIL 3"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// MODULE: cinterop
|
||||
// FILE: leakMemoryWithRunningThreadUnchecked.def
|
||||
---
|
||||
void test_RunInNewThread(void (*)());
|
||||
|
||||
// FILE: leakMemoryWithRunningThreadUnchecked.h
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void test_RunInNewThread(void (*)());
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
// FILE: leakMemoryWithRunningThreadUnchecked.cpp
|
||||
#include "leakMemoryWithRunningThreadUnchecked.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
|
||||
extern "C" void test_RunInNewThread(void (*f)()) {
|
||||
std::atomic<bool> haveRun(false);
|
||||
std::thread t([f, &haveRun]() {
|
||||
f();
|
||||
haveRun = true;
|
||||
while (true) {}
|
||||
});
|
||||
t.detach();
|
||||
while (!haveRun) {}
|
||||
}
|
||||
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(
|
||||
kotlin.experimental.ExperimentalNativeApi::class,
|
||||
kotlin.native.runtime.NativeRuntimeApi::class,
|
||||
kotlinx.cinterop.ExperimentalForeignApi::class
|
||||
)
|
||||
|
||||
import leakMemoryWithRunningThreadUnchecked.*
|
||||
import kotlin.concurrent.AtomicInt
|
||||
import kotlin.native.concurrent.*
|
||||
import kotlin.native.Platform
|
||||
import kotlin.test.*
|
||||
import kotlinx.cinterop.*
|
||||
|
||||
val global = AtomicInt(0)
|
||||
|
||||
fun ensureInititalized() {
|
||||
// Only needed with the legacy MM. TODO: Remove when legacy MM is gone.
|
||||
kotlin.native.initRuntimeIfNeeded()
|
||||
// Leak memory
|
||||
StableRef.create(Any())
|
||||
global.value = 1
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
Platform.isMemoryLeakCheckerActive = true
|
||||
kotlin.native.runtime.Debugging.forceCheckedShutdown = false
|
||||
assertTrue(global.value == 0)
|
||||
// Created a thread, made sure Kotlin is initialized there.
|
||||
test_RunInNewThread(staticCFunction(::ensureInititalized))
|
||||
assertTrue(global.value == 1)
|
||||
// Now exiting. With unchecked shutdown, we exit quietly, even though there're
|
||||
// unfinished threads with runtimes.
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// DISABLE_NATIVE: isAppleTarget=false
|
||||
// LANGUAGE: +ImplicitSignedToUnsignedIntegerConversion
|
||||
|
||||
// MODULE: cinterop
|
||||
// FILE: direct.def
|
||||
language = Objective-C
|
||||
headers = direct.h
|
||||
headerFilter = direct.h
|
||||
|
||||
// FILE: direct.h
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
__attribute__((objc_runtime_name("CC")))
|
||||
__attribute__((swift_name("CC")))
|
||||
@interface CallingConventions : NSObject
|
||||
|
||||
+ (uint64_t)regular:(uint64_t)arg;
|
||||
- (uint64_t)regular:(uint64_t)arg;
|
||||
|
||||
+ (uint64_t)direct:(uint64_t)arg __attribute__((objc_direct));
|
||||
- (uint64_t)direct:(uint64_t)arg __attribute__((objc_direct));
|
||||
|
||||
@end
|
||||
|
||||
@interface CallingConventions(Ext)
|
||||
|
||||
+ (uint64_t)regularExt:(uint64_t)arg;
|
||||
- (uint64_t)regularExt:(uint64_t)arg;
|
||||
|
||||
+ (uint64_t)directExt:(uint64_t)arg __attribute__((objc_direct));
|
||||
- (uint64_t)directExt:(uint64_t)arg __attribute__((objc_direct));
|
||||
|
||||
@end
|
||||
|
||||
__attribute__((objc_runtime_name("CCH")))
|
||||
__attribute__((swift_name("CCH")))
|
||||
@interface CallingConventionsHeir : CallingConventions
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
// FILE: direct.m
|
||||
#import "direct.h"
|
||||
|
||||
#define TEST_METHOD_IMPL(NAME) (uint64_t)NAME:(uint64_t)arg { return arg; }
|
||||
|
||||
@implementation CallingConventions : NSObject
|
||||
|
||||
+ TEST_METHOD_IMPL(regular);
|
||||
- TEST_METHOD_IMPL(regular);
|
||||
|
||||
+ TEST_METHOD_IMPL(direct);
|
||||
- TEST_METHOD_IMPL(direct);
|
||||
|
||||
@end
|
||||
|
||||
@implementation CallingConventions(Ext)
|
||||
|
||||
+ TEST_METHOD_IMPL(regularExt);
|
||||
- TEST_METHOD_IMPL(regularExt);
|
||||
|
||||
+ TEST_METHOD_IMPL(directExt);
|
||||
- TEST_METHOD_IMPL(directExt);
|
||||
|
||||
@end
|
||||
|
||||
@implementation CallingConventionsHeir
|
||||
|
||||
@end
|
||||
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
import direct.*
|
||||
import kotlinx.cinterop.*
|
||||
import kotlin.test.*
|
||||
|
||||
class CallingConventionsNativeHeir() : CallingConventions() {
|
||||
// nothing
|
||||
}
|
||||
|
||||
typealias CC = CallingConventions
|
||||
typealias CCH = CallingConventionsHeir
|
||||
typealias CCN = CallingConventionsNativeHeir
|
||||
|
||||
// KT-54610
|
||||
fun box(): String {
|
||||
autoreleasepool {
|
||||
val cc = CC()
|
||||
val cch = CCH()
|
||||
val ccn = CCN()
|
||||
|
||||
assertEquals(42UL, CC.regular(42))
|
||||
assertEquals(42UL, cc.regular(42))
|
||||
assertEquals(42UL, CC.regularExt(42))
|
||||
assertEquals(42UL, cc.regularExt(42))
|
||||
|
||||
assertEquals(42UL, CCH.regular(42))
|
||||
assertEquals(42UL, cch.regular(42))
|
||||
assertEquals(42UL, CCH.regularExt(42))
|
||||
assertEquals(42UL, cch.regularExt(42))
|
||||
|
||||
assertEquals(42UL, ccn.regular(42UL))
|
||||
assertEquals(42UL, ccn.regularExt(42UL))
|
||||
|
||||
assertEquals(42UL, CC.direct(42))
|
||||
assertEquals(42UL, cc.direct(42))
|
||||
assertEquals(42UL, CC.directExt(42))
|
||||
assertEquals(42UL, cc.directExt(42))
|
||||
|
||||
assertEquals(42UL, CCH.direct(42))
|
||||
assertEquals(42UL, cch .direct(42))
|
||||
assertEquals(42UL, CCH.directExt(42))
|
||||
assertEquals(42UL, cch .directExt(42))
|
||||
|
||||
assertEquals(42UL, ccn .direct(42UL))
|
||||
assertEquals(42UL, ccn .directExt(42UL))
|
||||
}
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// `import objcnames` somehow works only with NATIVE_STANDALONE test directive
|
||||
// NATIVE_STANDALONE
|
||||
// DISABLE_NATIVE: isAppleTarget=false
|
||||
|
||||
// MODULE: a
|
||||
// FILE: a.def
|
||||
language = Objective-C
|
||||
---
|
||||
#import <Foundation/Foundation.h>
|
||||
#include <stdio.h>
|
||||
|
||||
struct ForwardDeclaredStruct;
|
||||
@class ForwardDeclaredClass;
|
||||
@protocol ForwardDeclaredProtocol;
|
||||
|
||||
NSString* consumeProtocol(id<ForwardDeclaredProtocol> s) {
|
||||
return [NSString stringWithUTF8String:"Protocol"];
|
||||
}
|
||||
NSString* consumeClass(ForwardDeclaredClass* s) {
|
||||
return [NSString stringWithUTF8String:"Class"];
|
||||
}
|
||||
NSString* consumeStruct(struct ForwardDeclaredStruct* s) {
|
||||
return [NSString stringWithUTF8String:"Struct"];
|
||||
}
|
||||
|
||||
// MODULE: b
|
||||
// FILE: b.def
|
||||
language = Objective-C
|
||||
headers = b.h
|
||||
---
|
||||
|
||||
// FILE: b.h
|
||||
#define NS_FORMAT_ARGUMENT(X)
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@protocol ForwardDeclaredProtocol
|
||||
@end
|
||||
|
||||
@interface ForwardDeclaredProtocolImpl : NSObject<ForwardDeclaredProtocol>
|
||||
@end;
|
||||
|
||||
|
||||
@interface ForwardDeclaredClass : NSObject
|
||||
@end;
|
||||
|
||||
struct ForwardDeclaredStruct {};
|
||||
|
||||
id<ForwardDeclaredProtocol> produceProtocol();
|
||||
ForwardDeclaredClass* produceClass();
|
||||
struct ForwardDeclaredStruct* produceStruct();
|
||||
|
||||
// FILE: b.m
|
||||
#import "b.h"
|
||||
|
||||
@implementation ForwardDeclaredProtocolImpl : NSObject
|
||||
@end;
|
||||
|
||||
@implementation ForwardDeclaredClass : NSObject
|
||||
@end;
|
||||
|
||||
id<ForwardDeclaredProtocol> produceProtocol() {
|
||||
return [ForwardDeclaredProtocolImpl new];
|
||||
}
|
||||
|
||||
ForwardDeclaredClass* produceClass() {
|
||||
return [ForwardDeclaredClass new];
|
||||
}
|
||||
|
||||
struct ForwardDeclaredStruct S;
|
||||
|
||||
struct ForwardDeclaredStruct* produceStruct() {
|
||||
return &S;
|
||||
}
|
||||
|
||||
// MODULE: lib(a)
|
||||
// FILE: lib.kt
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
import cnames.structs.ForwardDeclaredStruct
|
||||
import objcnames.classes.ForwardDeclaredClass
|
||||
import objcnames.protocols.ForwardDeclaredProtocolProtocol
|
||||
import a.*
|
||||
import kotlinx.cinterop.*
|
||||
|
||||
fun testStruct(s: Any?) = consumeStruct(s as CPointer<ForwardDeclaredStruct>)
|
||||
fun testClass(s: Any?) = consumeClass(s as ForwardDeclaredClass)
|
||||
fun testProtocol(s: Any?) = consumeProtocol(s as ForwardDeclaredProtocolProtocol)
|
||||
|
||||
|
||||
fun <T : ForwardDeclaredClass> testClass2Impl(s: Any?) = consumeClass(s as T)
|
||||
fun <T : ForwardDeclaredProtocolProtocol> testProtocol2Impl(s: Any?) = consumeProtocol(s as T)
|
||||
|
||||
fun testClass2(s: Any?) = testClass2Impl<ForwardDeclaredClass>(s)
|
||||
fun testProtocol2(s: Any?) = testProtocol2Impl<ForwardDeclaredProtocolProtocol>(s)
|
||||
|
||||
// MODULE: main(lib, b)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
import a.*
|
||||
import b.*
|
||||
|
||||
|
||||
fun box(): String {
|
||||
if (testStruct(produceStruct()) != "Struct") throw IllegalStateException()
|
||||
if (testClass(produceClass()) != "Class") throw IllegalStateException()
|
||||
if (testProtocol(produceProtocol()) != "Protocol") throw IllegalStateException()
|
||||
if (testClass2(produceClass()) != "Class") throw IllegalStateException()
|
||||
if (testProtocol2(produceProtocol()) != "Protocol") throw IllegalStateException()
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// DISABLE_NATIVE: isAppleTarget=false
|
||||
|
||||
// FREE_CINTEROP_ARGS: -compiler-option -fmodule-map-file=$generatedSourcesDir/cinterop/module_library.modulemap
|
||||
// MODULE: cinterop
|
||||
// FILE: module_library.def
|
||||
language = Objective-C
|
||||
modules = module_library
|
||||
|
||||
// FILE: module_library.modulemap
|
||||
module module_library {
|
||||
umbrella header "module_library_umbrella.h"
|
||||
|
||||
export *
|
||||
module * { export * }
|
||||
}
|
||||
|
||||
// FILE: module_library_umbrella.h
|
||||
#import <foo.h>
|
||||
|
||||
// FILE: foo.h
|
||||
#define ANSWER 42
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
import module_library.*
|
||||
|
||||
fun box(): String {
|
||||
val answer = ANSWER
|
||||
if (answer != 42)
|
||||
return "FAIL: $answer"
|
||||
return "OK"
|
||||
}
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// DISABLE_NATIVE: isAppleTarget=false
|
||||
// Without a fix, fails in two-stage mode.
|
||||
// The bug was accidentally fixed with lazy IR for caches, so testing it with this feature disabled:
|
||||
// FREE_COMPILER_ARGS: -Xlazy-ir-for-caches=disable
|
||||
|
||||
// MODULE: cinterop
|
||||
// FILE: objclib.def
|
||||
language = Objective-C
|
||||
headers = objclib.h
|
||||
headerFilter = objclib.h **/NSObject.h **/NSDate.h **/NSUUID.h
|
||||
|
||||
// FILE: objclib.h
|
||||
#import <Foundation/NSObject.h>
|
||||
#import <Foundation/NSDate.h>
|
||||
#import <Foundation/NSUUID.h>
|
||||
|
||||
@interface MyClass1 : NSObject
|
||||
@end
|
||||
|
||||
@interface MyClass2 : NSObject
|
||||
@end
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
import kotlin.reflect.*
|
||||
import kotlin.test.*
|
||||
import objclib.*
|
||||
|
||||
// https://youtrack.jetbrains.com/issue/KT-48816
|
||||
open class Base<Ref> {
|
||||
operator fun KProperty1<Ref, NSUUID>.getValue(ref: Base<Ref>, property: KProperty<*>): NSUUID? {
|
||||
return null
|
||||
}
|
||||
operator fun KProperty1<Ref, NSDate>.getValue(ref: Base<Ref>, property: KProperty<*>): NSDate? {
|
||||
return null
|
||||
}
|
||||
}
|
||||
class Usage: Base<B>()
|
||||
class B
|
||||
|
||||
// The compilation should fail with the above;
|
||||
// but anyway try to actually use the code, just to ensure it doesn't get DCEd:
|
||||
|
||||
val B.uuid: NSUUID get() = fail()
|
||||
val B.date: NSDate get() = fail()
|
||||
|
||||
fun test1() {
|
||||
val uuidProperty = B::uuid
|
||||
val dateProperty = B::date
|
||||
val usage = Usage()
|
||||
with(usage) {
|
||||
assertNull(uuidProperty.getValue(usage, uuidProperty))
|
||||
assertNull(dateProperty.getValue(usage, dateProperty))
|
||||
}
|
||||
}
|
||||
|
||||
// One more reproducer, just in case:
|
||||
class Property<out R>
|
||||
|
||||
open class Base2 {
|
||||
fun getValue(property: Property<MyClass1>) = null
|
||||
fun getValue(property: Property<MyClass2>) = null
|
||||
}
|
||||
class Usage2 : Base2()
|
||||
|
||||
fun test2() {
|
||||
val usage = Usage2()
|
||||
assertNull(usage.getValue(Property<MyClass1>()))
|
||||
assertNull(usage.getValue(Property<MyClass2>()))
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
test1()
|
||||
test2()
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// DISABLE_NATIVE: isAppleTarget=false
|
||||
// The bug was accidentally fixed with lazy IR for caches, so testing it with this feature enabled, and disabled(in other test file):
|
||||
// FREE_COMPILER_ARGS: -Xlazy-ir-for-caches=enable
|
||||
|
||||
// MODULE: cinterop
|
||||
// FILE: objclib.def
|
||||
language = Objective-C
|
||||
headers = objclib.h
|
||||
headerFilter = objclib.h **/NSObject.h **/NSDate.h **/NSUUID.h
|
||||
|
||||
// FILE: objclib.h
|
||||
#import <Foundation/NSObject.h>
|
||||
#import <Foundation/NSDate.h>
|
||||
#import <Foundation/NSUUID.h>
|
||||
|
||||
@interface MyClass1 : NSObject
|
||||
@end
|
||||
|
||||
@interface MyClass2 : NSObject
|
||||
@end
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
import kotlin.reflect.*
|
||||
import kotlin.test.*
|
||||
import objclib.*
|
||||
|
||||
// https://youtrack.jetbrains.com/issue/KT-48816
|
||||
open class Base<Ref> {
|
||||
operator fun KProperty1<Ref, NSUUID>.getValue(ref: Base<Ref>, property: KProperty<*>): NSUUID? {
|
||||
return null
|
||||
}
|
||||
operator fun KProperty1<Ref, NSDate>.getValue(ref: Base<Ref>, property: KProperty<*>): NSDate? {
|
||||
return null
|
||||
}
|
||||
}
|
||||
class Usage: Base<B>()
|
||||
class B
|
||||
|
||||
// The compilation should fail with the above;
|
||||
// but anyway try to actually use the code, just to ensure it doesn't get DCEd:
|
||||
|
||||
val B.uuid: NSUUID get() = fail()
|
||||
val B.date: NSDate get() = fail()
|
||||
|
||||
fun test1() {
|
||||
val uuidProperty = B::uuid
|
||||
val dateProperty = B::date
|
||||
val usage = Usage()
|
||||
with(usage) {
|
||||
assertNull(uuidProperty.getValue(usage, uuidProperty))
|
||||
assertNull(dateProperty.getValue(usage, dateProperty))
|
||||
}
|
||||
}
|
||||
|
||||
// One more reproducer, just in case:
|
||||
class Property<out R>
|
||||
|
||||
open class Base2 {
|
||||
fun getValue(property: Property<MyClass1>) = null
|
||||
fun getValue(property: Property<MyClass2>) = null
|
||||
}
|
||||
class Usage2 : Base2()
|
||||
|
||||
fun test2() {
|
||||
val usage = Usage2()
|
||||
assertNull(usage.getValue(Property<MyClass1>()))
|
||||
assertNull(usage.getValue(Property<MyClass2>()))
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
test1()
|
||||
test2()
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// `import objcnames` somehow works only with NATIVE_STANDALONE test directive
|
||||
// NATIVE_STANDALONE
|
||||
// The test checks no collision between kt49034.__darwin_fp_control and platform.posix.__darwin_fp_control
|
||||
// The test makes sense only on Apple x64 targets, where `class __darwin_fp_control` present in posix platform lib
|
||||
// DISABLE_NATIVE: isAppleTarget=false
|
||||
// DISABLE_NATIVE: targetArchitecture=ARM64
|
||||
|
||||
// MODULE: cinterop
|
||||
// FILE: kt49034.def
|
||||
headers = kt49034.h
|
||||
language = Objective-C
|
||||
|
||||
// FILE: kt49034.h
|
||||
@class __darwin_fp_control;
|
||||
void foo(__darwin_fp_control*);
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
import objcnames.classes.__darwin_fp_control
|
||||
|
||||
open class C<T : kotlinx.cinterop.ObjCObject>
|
||||
|
||||
class D : C<__darwin_fp_control>()
|
||||
|
||||
fun box(): String {
|
||||
println(D())
|
||||
return "OK"
|
||||
}
|
||||
|
||||
// FILE: checkPlatformDarwinFPControl.kt
|
||||
import platform.posix.__darwin_fp_control
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// The test depends on collision between kt49034.JSContext and platform.JavaScriptCore.JSContext
|
||||
// DISABLE_NATIVE: isAppleTarget=false
|
||||
// There is no JavaScriptCore on watchOS.
|
||||
// DISABLE_NATIVE: targetFamily=WATCHOS
|
||||
|
||||
// MODULE: cinterop
|
||||
// FILE: kt49034.def
|
||||
headers = kt49034.h
|
||||
|
||||
// FILE: kt49034.h
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct JSContext;
|
||||
|
||||
struct JSContext* bar();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
// FILE: impl.c
|
||||
#include "kt49034.h"
|
||||
|
||||
struct JSContext {
|
||||
int field;
|
||||
};
|
||||
|
||||
struct JSContext global = { 15 };
|
||||
|
||||
extern "C" struct JSContext* bar() {
|
||||
return &global;
|
||||
}
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
import kt49034.bar
|
||||
import cnames.structs.JSContext
|
||||
import kotlinx.cinterop.CPointer
|
||||
|
||||
fun baz(s: CPointer<JSContext>) {
|
||||
println(s)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
baz(bar()!!)
|
||||
return "OK"
|
||||
}
|
||||
|
||||
// FILE: checkPlatformJavaScriptCore.kt
|
||||
import platform.JavaScriptCore.JSContext
|
||||
@@ -0,0 +1,39 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// DISABLE_NATIVE: isAppleTarget=false
|
||||
|
||||
// FREE_CINTEROP_ARGS: -compiler-option -F$generatedSourcesDir/cinterop
|
||||
// MODULE: cinterop
|
||||
// FILE: objclib.def
|
||||
language = Objective-C
|
||||
modules = Foo
|
||||
---
|
||||
static int getDefInt() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int getFrameworkIntFromDef() {
|
||||
return getFrameworkInt();
|
||||
}
|
||||
|
||||
// FILE: Foo.framework/Headers/Foo.h
|
||||
static int getFrameworkInt() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// FILE: Foo.framework/Modules/module.modulemap
|
||||
framework module Foo {
|
||||
umbrella header "Foo.h"
|
||||
}
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
import kotlin.test.*
|
||||
import objclib.*
|
||||
|
||||
fun box(): String {
|
||||
assertEquals(1, getFrameworkInt())
|
||||
assertEquals(2, getDefInt())
|
||||
assertEquals(1, getFrameworkIntFromDef())
|
||||
return "OK"
|
||||
}
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// DISABLE_NATIVE: isAppleTarget=false
|
||||
|
||||
// MODULE: cinterop
|
||||
// FILE: lib.def
|
||||
language = Objective-C
|
||||
headers = lib.h
|
||||
headerFilter = lib.h
|
||||
|
||||
// FILE: lib.h
|
||||
#import <Foundation/NSObject.h>
|
||||
#import <Foundation/NSDate.h>
|
||||
#import <Foundation/NSUUID.h>
|
||||
|
||||
@interface ObjCClass : NSObject
|
||||
- (NSString*)fooWithArg:(int)arg arg2:(NSString*)arg2;
|
||||
- (NSString*)fooWithArg:(int)ohNoOtherName name2:(NSString*)name2;
|
||||
- (NSString*)fooWithArg:(int)arg name3:(NSString*)name3;
|
||||
@end
|
||||
|
||||
// FILE: lib.m
|
||||
#import "lib.h"
|
||||
|
||||
@implementation ObjCClass {
|
||||
}
|
||||
|
||||
- (NSString*)fooWithArg:(int)arg arg2:(NSString*)arg2 {
|
||||
return @"A";
|
||||
}
|
||||
|
||||
- (NSString*)fooWithArg:(int)ohNoOtherName name2:(NSString*)name2 {
|
||||
return @"B";
|
||||
}
|
||||
|
||||
- (NSString*)fooWithArg:(int)arg name3:(NSString*)name3 {
|
||||
return @"C";
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
// required for K1
|
||||
@file:Suppress("CONFLICTING_OVERLOADS", "UNRESOLVED_REFERENCE", "API_NOT_AVAILABLE")
|
||||
|
||||
import lib.ObjCClass
|
||||
import kotlinx.cinterop.ObjCSignatureOverride
|
||||
|
||||
class OverrideAll : ObjCClass() {
|
||||
@ObjCSignatureOverride
|
||||
override fun fooWithArg(arg: Int, arg2: String?) = "D"
|
||||
@ObjCSignatureOverride
|
||||
override fun fooWithArg(ohNoOtherName: Int, name2: String?) = "E"
|
||||
@ObjCSignatureOverride
|
||||
override fun fooWithArg(arg: Int, name3: String?) = "F"
|
||||
}
|
||||
|
||||
class OverrideNone : ObjCClass() {
|
||||
}
|
||||
|
||||
class OverrideOne : ObjCClass() {
|
||||
override fun fooWithArg(arg: Int, arg2: String?) = "G"
|
||||
}
|
||||
|
||||
class OverrideWithDifferentFirstArgName : ObjCClass() {
|
||||
@ObjCSignatureOverride
|
||||
override fun fooWithArg(a: Int, arg2: String?) = "H"
|
||||
@ObjCSignatureOverride
|
||||
override fun fooWithArg(b: Int, name2: String?) = "I"
|
||||
@ObjCSignatureOverride
|
||||
override fun fooWithArg(c: Int, name3: String?) = "J"
|
||||
}
|
||||
|
||||
fun test(x: ObjCClass, expected: String) {
|
||||
val res = x.fooWithArg(arg = 0, arg2 = "") +
|
||||
x.fooWithArg(ohNoOtherName = 0, name2="") +
|
||||
x.fooWithArg(arg = 0, name3 = "")
|
||||
if (res != expected) throw IllegalStateException("Fail ${x::class}: ${res} instead of $expected")
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
test(ObjCClass(), "ABC")
|
||||
test(OverrideAll(), "DEF")
|
||||
test(OverrideNone(), "ABC")
|
||||
test(OverrideOne(), "GBC")
|
||||
test(OverrideWithDifferentFirstArgName(), "HIJ")
|
||||
|
||||
// Also test non-virtual calls
|
||||
val x1 = OverrideAll()
|
||||
val res1 = x1.fooWithArg(arg = 0, arg2 = "") +
|
||||
x1.fooWithArg(ohNoOtherName = 0, name2="") +
|
||||
x1.fooWithArg(arg = 0, name3 = "")
|
||||
if (res1 != "DEF") throw IllegalStateException("Fail OverrideAll non-virtual: ${res1} instead of DEF")
|
||||
|
||||
val x2 = OverrideNone()
|
||||
val res2 = x2.fooWithArg(arg = 0, arg2 = "") +
|
||||
x2.fooWithArg(ohNoOtherName = 0, name2="") +
|
||||
x2.fooWithArg(arg = 0, name3 = "")
|
||||
if (res2 != "ABC") throw IllegalStateException("Fail OverrideNone non-virtual: ${res2} instead of ABC")
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// DISABLE_NATIVE: isAppleTarget=false
|
||||
|
||||
// MODULE: cinterop
|
||||
// FILE: objclib.def
|
||||
language = Objective-C
|
||||
headers = objclib.h
|
||||
headerFilter = objclib.h
|
||||
|
||||
// FILE: objclib.h
|
||||
#import <objc/NSObject.h>
|
||||
|
||||
static NSObject* __weak globalObject = nil;
|
||||
|
||||
void setObject(NSObject* obj) {
|
||||
globalObject = obj;
|
||||
}
|
||||
|
||||
bool isObjectAlive() {
|
||||
return globalObject != nil;
|
||||
}
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(ObsoleteWorkersApi::class, kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
import kotlin.native.concurrent.*
|
||||
import kotlin.test.*
|
||||
import kotlinx.cinterop.autoreleasepool
|
||||
import objclib.*
|
||||
|
||||
fun box(): String {
|
||||
val success = autoreleasepool {
|
||||
run()
|
||||
}
|
||||
// Experimental MM supports arbitrary object sharing.
|
||||
return if (success) "OK" else "FAIL"
|
||||
}
|
||||
|
||||
private class NSObjectImpl : NSObject() {
|
||||
var x = 111
|
||||
}
|
||||
|
||||
fun run() = withWorker {
|
||||
val obj = NSObjectImpl()
|
||||
setObject(obj)
|
||||
|
||||
try {
|
||||
execute(TransferMode.SAFE, {}) {
|
||||
isObjectAlive()
|
||||
}.result
|
||||
} catch (e: Throwable) {
|
||||
false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2010-2024 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// MODULE: cinterop
|
||||
// FILE: part1.part2.def
|
||||
package package1
|
||||
---
|
||||
#define OK_STRING "OK"
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
import package1.*
|
||||
|
||||
fun box(): String = OK_STRING
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2010-2024 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// MODULE: cinterop
|
||||
// FILE: filename1.filename2.def
|
||||
package package1.package2
|
||||
---
|
||||
#define OK_STRING "OK"
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
import package1.package2.*
|
||||
|
||||
fun box(): String = OK_STRING
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright 2010-2024 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// MODULE: cinterop
|
||||
// FILE: root1.root2.def
|
||||
---
|
||||
#define OK_STRING "OK"
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
import root2.root1.*
|
||||
|
||||
fun box(): String = OK_STRING
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2010-2024 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// MODULE: cinterop
|
||||
// FILE: packages.def
|
||||
package package1
|
||||
---
|
||||
#define OK_STRING "OK"
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
import package1.*
|
||||
|
||||
fun box(): String = OK_STRING
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2010-2024 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// MODULE: cinterop
|
||||
// FILE: packages.def
|
||||
package package1.package2
|
||||
---
|
||||
#define OK_STRING "OK"
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
import package1.package2.*
|
||||
|
||||
fun box(): String = OK_STRING
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright 2010-2024 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// MODULE: cinterop
|
||||
// FILE: root1.def
|
||||
---
|
||||
#define OK_STRING "OK"
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
import root1.*
|
||||
|
||||
fun box(): String = OK_STRING
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// NATIVE_STANDALONE
|
||||
// MODULE: cinterop
|
||||
// FILE: threadStates.def
|
||||
language = C
|
||||
---
|
||||
void assertNativeThreadState();
|
||||
|
||||
void runCallback(void(*callback)(void)) {
|
||||
assertNativeThreadState();
|
||||
callback();
|
||||
assertNativeThreadState();
|
||||
}
|
||||
|
||||
// FILE: threadStates.cpp
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// Implemented in the runtime for test purposes.
|
||||
extern "C" bool Kotlin_Debugging_isThreadStateNative();
|
||||
|
||||
extern "C" void assertNativeThreadState() {
|
||||
if (!Kotlin_Debugging_isThreadStateNative()) {
|
||||
printf("Incorrect thread state. Expected native thread state.");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlin.native.runtime.NativeRuntimeApi::class, kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
import kotlin.native.runtime.Debugging
|
||||
import kotlin.test.*
|
||||
import kotlinx.cinterop.*
|
||||
import threadStates.*
|
||||
|
||||
fun box(): String {
|
||||
runCallback(staticCFunction { ->
|
||||
assertRunnableThreadState()
|
||||
})
|
||||
assertRunnableThreadState()
|
||||
return "OK"
|
||||
}
|
||||
|
||||
fun assertRunnableThreadState() {
|
||||
assertTrue(Debugging.isThreadStateRunnable)
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// NATIVE_STANDALONE
|
||||
// MODULE: cinterop
|
||||
// FILE: threadStates.def
|
||||
language = C
|
||||
---
|
||||
void runInNewThread(void(*callback)(void));
|
||||
|
||||
// FILE: threadStates.cpp
|
||||
#include <thread>
|
||||
|
||||
extern "C" void runInNewThread(void(*callback)(void)) {
|
||||
std::thread t([callback]() {
|
||||
callback();
|
||||
});
|
||||
t.join();
|
||||
}
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlin.native.runtime.NativeRuntimeApi::class, kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
import kotlin.native.runtime.Debugging
|
||||
import kotlin.test.*
|
||||
import kotlinx.cinterop.*
|
||||
import threadStates.*
|
||||
|
||||
fun box(): String {
|
||||
runInNewThread(staticCFunction { ->
|
||||
assertRunnableThreadState()
|
||||
})
|
||||
return "OK"
|
||||
}
|
||||
|
||||
fun assertRunnableThreadState() {
|
||||
assertTrue(Debugging.isThreadStateRunnable)
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// NATIVE_STANDALONE
|
||||
// MODULE: cinterop
|
||||
// FILE: threadStates.def
|
||||
language = C
|
||||
---
|
||||
void assertNativeThreadState();
|
||||
|
||||
void runCallback(void(*callback)(void)) {
|
||||
assertNativeThreadState();
|
||||
callback();
|
||||
assertNativeThreadState();
|
||||
}
|
||||
|
||||
// FILE: threadStates.cpp
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// Implemented in the runtime for test purposes.
|
||||
extern "C" bool Kotlin_Debugging_isThreadStateNative();
|
||||
|
||||
extern "C" void assertNativeThreadState() {
|
||||
if (!Kotlin_Debugging_isThreadStateNative()) {
|
||||
printf("Incorrect thread state. Expected native thread state.");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlin.native.runtime.NativeRuntimeApi::class, kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
import kotlin.native.runtime.Debugging
|
||||
import kotlin.test.*
|
||||
import kotlinx.cinterop.staticCFunction
|
||||
import threadStates.*
|
||||
|
||||
fun box(): String {
|
||||
try {
|
||||
runCallback(staticCFunction(::throwException))
|
||||
} catch (e: CustomException) {
|
||||
assertRunnableThreadState()
|
||||
return "OK"
|
||||
} catch (e: Throwable) {
|
||||
assertRunnableThreadState()
|
||||
fail("Wrong exception type: ${e.message}")
|
||||
}
|
||||
fail("No exception thrown")
|
||||
}
|
||||
|
||||
fun assertRunnableThreadState() {
|
||||
assertTrue(Debugging.isThreadStateRunnable)
|
||||
}
|
||||
|
||||
class CustomException() : Exception()
|
||||
|
||||
fun throwException() {
|
||||
assertRunnableThreadState()
|
||||
throw CustomException()
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// NATIVE_STANDALONE
|
||||
// MODULE: cinterop
|
||||
// FILE: threadStates.def
|
||||
language = C
|
||||
---
|
||||
void assertNativeThreadState();
|
||||
|
||||
void runCallback(void(*callback)(void)) {
|
||||
assertNativeThreadState();
|
||||
callback();
|
||||
assertNativeThreadState();
|
||||
}
|
||||
|
||||
// FILE: threadStates.cpp
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// Implemented in the runtime for test purposes.
|
||||
extern "C" bool Kotlin_Debugging_isThreadStateNative();
|
||||
|
||||
extern "C" void assertNativeThreadState() {
|
||||
if (!Kotlin_Debugging_isThreadStateNative()) {
|
||||
printf("Incorrect thread state. Expected native thread state.");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlin.native.runtime.NativeRuntimeApi::class, kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
import kotlin.native.runtime.Debugging
|
||||
import kotlin.test.*
|
||||
import kotlinx.cinterop.staticCFunction
|
||||
import threadStates.*
|
||||
|
||||
fun box(): String {
|
||||
try {
|
||||
runCallback(staticCFunction(::throwException))
|
||||
} catch (e: CustomException) {
|
||||
assertRunnableThreadState()
|
||||
return "OK"
|
||||
} finally {
|
||||
assertRunnableThreadState()
|
||||
}
|
||||
fail("No exception thrown")
|
||||
}
|
||||
|
||||
fun assertRunnableThreadState() {
|
||||
assertTrue(Debugging.isThreadStateRunnable)
|
||||
}
|
||||
|
||||
class CustomException() : Exception()
|
||||
|
||||
fun throwException() {
|
||||
assertRunnableThreadState()
|
||||
throw CustomException()
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// NATIVE_STANDALONE
|
||||
// MODULE: cinterop
|
||||
// FILE: threadStates.def
|
||||
language = C
|
||||
---
|
||||
void assertNativeThreadState();
|
||||
|
||||
void runCallback(void(*callback)(void)) {
|
||||
assertNativeThreadState();
|
||||
callback();
|
||||
assertNativeThreadState();
|
||||
}
|
||||
|
||||
// FILE: threadStates.cpp
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// Implemented in the runtime for test purposes.
|
||||
extern "C" bool Kotlin_Debugging_isThreadStateNative();
|
||||
|
||||
extern "C" void assertNativeThreadState() {
|
||||
if (!Kotlin_Debugging_isThreadStateNative()) {
|
||||
printf("Incorrect thread state. Expected native thread state.");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlin.native.runtime.NativeRuntimeApi::class, kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
import kotlin.native.runtime.Debugging
|
||||
import kotlin.test.*
|
||||
import kotlinx.cinterop.staticCFunction
|
||||
import threadStates.*
|
||||
|
||||
fun box(): String {
|
||||
try {
|
||||
try {
|
||||
runCallback(staticCFunction(::throwException))
|
||||
} finally {
|
||||
assertRunnableThreadState()
|
||||
}
|
||||
assertRunnableThreadState()
|
||||
} catch (_: CustomException) {}
|
||||
return "OK"
|
||||
}
|
||||
|
||||
fun assertRunnableThreadState() {
|
||||
assertTrue(Debugging.isThreadStateRunnable)
|
||||
}
|
||||
|
||||
class CustomException() : Exception()
|
||||
|
||||
fun throwException() {
|
||||
assertRunnableThreadState()
|
||||
throw CustomException()
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// NATIVE_STANDALONE
|
||||
@file:OptIn(kotlin.native.runtime.NativeRuntimeApi::class, kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
import kotlin.native.runtime.Debugging
|
||||
import kotlin.test.*
|
||||
import kotlinx.cinterop.*
|
||||
|
||||
fun box(): String {
|
||||
val funPtr = staticCFunction { ->
|
||||
assertRunnableThreadState()
|
||||
}
|
||||
assertRunnableThreadState()
|
||||
funPtr()
|
||||
assertRunnableThreadState()
|
||||
return "OK"
|
||||
}
|
||||
|
||||
fun assertRunnableThreadState() {
|
||||
assertTrue(Debugging.isThreadStateRunnable)
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// NATIVE_STANDALONE
|
||||
// MODULE: cinterop
|
||||
// FILE: threadStates.def
|
||||
language = C
|
||||
---
|
||||
#include <stdint.h>
|
||||
|
||||
void assertNativeThreadState();
|
||||
|
||||
int32_t answer() {
|
||||
assertNativeThreadState();
|
||||
return 42;
|
||||
}
|
||||
|
||||
// FILE: threadStates.cpp
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// Implemented in the runtime for test purposes.
|
||||
extern "C" bool Kotlin_Debugging_isThreadStateNative();
|
||||
|
||||
extern "C" void assertNativeThreadState() {
|
||||
if (!Kotlin_Debugging_isThreadStateNative()) {
|
||||
printf("Incorrect thread state. Expected native thread state.");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlin.native.runtime.NativeRuntimeApi::class, kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
import kotlin.native.runtime.Debugging
|
||||
import kotlin.test.*
|
||||
import kotlinx.cinterop.*
|
||||
import threadStates.*
|
||||
|
||||
fun box(): String {
|
||||
answer()
|
||||
assertRunnableThreadState()
|
||||
return "OK"
|
||||
}
|
||||
|
||||
fun assertRunnableThreadState() {
|
||||
assertTrue(Debugging.isThreadStateRunnable)
|
||||
}
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// NATIVE_STANDALONE
|
||||
// MODULE: cinterop
|
||||
// FILE: threadStates.def
|
||||
language = C
|
||||
---
|
||||
void assertNativeThreadState();
|
||||
|
||||
void runCallback(void(*callback)(void)) {
|
||||
assertNativeThreadState();
|
||||
callback();
|
||||
assertNativeThreadState();
|
||||
}
|
||||
|
||||
// FILE: threadStates.cpp
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// Implemented in the runtime for test purposes.
|
||||
extern "C" bool Kotlin_Debugging_isThreadStateNative();
|
||||
|
||||
extern "C" void assertNativeThreadState() {
|
||||
if (!Kotlin_Debugging_isThreadStateNative()) {
|
||||
printf("Incorrect thread state. Expected native thread state.");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlin.native.runtime.NativeRuntimeApi::class, kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
import kotlin.native.runtime.Debugging
|
||||
import kotlin.test.*
|
||||
import kotlinx.cinterop.staticCFunction
|
||||
import threadStates.*
|
||||
|
||||
fun box(): String {
|
||||
try {
|
||||
runCallback(staticCFunction { ->
|
||||
assertRunnableThreadState()
|
||||
runCallback(staticCFunction(::throwException))
|
||||
})
|
||||
} catch (e: CustomException) {
|
||||
assertRunnableThreadState()
|
||||
return "OK"
|
||||
} catch (e: Throwable) {
|
||||
assertRunnableThreadState()
|
||||
fail("Wrong exception type: ${e.message}")
|
||||
}
|
||||
fail("No exception thrown")
|
||||
}
|
||||
|
||||
fun assertRunnableThreadState() {
|
||||
assertTrue(Debugging.isThreadStateRunnable)
|
||||
}
|
||||
|
||||
class CustomException() : Exception()
|
||||
|
||||
fun throwException() {
|
||||
assertRunnableThreadState()
|
||||
throw CustomException()
|
||||
}
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// NATIVE_STANDALONE
|
||||
// MODULE: cinterop
|
||||
// FILE: threadStates.def
|
||||
language = C
|
||||
---
|
||||
void assertNativeThreadState();
|
||||
|
||||
void runCallback(void(*callback)(void)) {
|
||||
assertNativeThreadState();
|
||||
callback();
|
||||
assertNativeThreadState();
|
||||
}
|
||||
|
||||
// FILE: threadStates.cpp
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// Implemented in the runtime for test purposes.
|
||||
extern "C" bool Kotlin_Debugging_isThreadStateNative();
|
||||
|
||||
extern "C" void assertNativeThreadState() {
|
||||
if (!Kotlin_Debugging_isThreadStateNative()) {
|
||||
printf("Incorrect thread state. Expected native thread state.");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlin.native.runtime.NativeRuntimeApi::class, kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
import kotlin.native.runtime.Debugging
|
||||
import kotlin.test.*
|
||||
import kotlinx.cinterop.staticCFunction
|
||||
import threadStates.*
|
||||
|
||||
fun box(): String {
|
||||
try {
|
||||
runCallback(staticCFunction { ->
|
||||
assertRunnableThreadState()
|
||||
runCallback(staticCFunction(::throwException))
|
||||
})
|
||||
} catch (e: CustomException) {
|
||||
assertRunnableThreadState()
|
||||
return "OK"
|
||||
} finally {
|
||||
assertRunnableThreadState()
|
||||
}
|
||||
fail("No exception thrown")
|
||||
}
|
||||
|
||||
fun assertRunnableThreadState() {
|
||||
assertTrue(Debugging.isThreadStateRunnable)
|
||||
}
|
||||
|
||||
class CustomException() : Exception()
|
||||
|
||||
fun throwException() {
|
||||
assertRunnableThreadState()
|
||||
throw CustomException()
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// NATIVE_STANDALONE
|
||||
// MODULE: cinterop
|
||||
// FILE: threadStates.def
|
||||
language = C
|
||||
---
|
||||
#include <stdint.h>
|
||||
|
||||
void assertNativeThreadState();
|
||||
|
||||
void runCallback(void(*callback)(void)) {
|
||||
assertNativeThreadState();
|
||||
callback();
|
||||
assertNativeThreadState();
|
||||
}
|
||||
|
||||
int32_t answer() {
|
||||
assertNativeThreadState();
|
||||
return 42;
|
||||
}
|
||||
|
||||
// FILE: threadStates.cpp
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// Implemented in the runtime for test purposes.
|
||||
extern "C" bool Kotlin_Debugging_isThreadStateNative();
|
||||
|
||||
extern "C" void assertNativeThreadState() {
|
||||
if (!Kotlin_Debugging_isThreadStateNative()) {
|
||||
printf("Incorrect thread state. Expected native thread state.");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlin.native.runtime.NativeRuntimeApi::class, kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
import kotlin.native.runtime.Debugging
|
||||
import kotlin.test.*
|
||||
import kotlinx.cinterop.*
|
||||
import threadStates.*
|
||||
|
||||
fun box(): String {
|
||||
runCallback(staticCFunction { ->
|
||||
assertRunnableThreadState()
|
||||
answer()
|
||||
Unit
|
||||
})
|
||||
assertRunnableThreadState()
|
||||
return "OK"
|
||||
}
|
||||
|
||||
fun assertRunnableThreadState() {
|
||||
assertTrue(Debugging.isThreadStateRunnable)
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// MODULE: cinterop
|
||||
// FILE: toKString.def
|
||||
---
|
||||
const char* empty() { return ""; }
|
||||
const char* foo() { return "foo"; }
|
||||
const char* kuku() { return "куку"; }
|
||||
const char* invalid_utf8() { return "\x85\xAF"; }
|
||||
const char* zero_in_the_middle() { return "before zero\0after zero"; }
|
||||
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
import toKString.*
|
||||
import kotlinx.cinterop.*
|
||||
import kotlin.native.*
|
||||
import kotlin.test.*
|
||||
|
||||
fun box(): String {
|
||||
assertEquals("", empty()!!.toKStringFromUtf8())
|
||||
assertEquals("foo", foo()!!.toKStringFromUtf8())
|
||||
assertEquals("куку", kuku()!!.toKStringFromUtf8())
|
||||
assertEquals("\uFFFD\uFFFD", invalid_utf8()!!.toKStringFromUtf8())
|
||||
assertEquals("before zero", zero_in_the_middle()!!.toKStringFromUtf8())
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// FILECHECK_STAGE: CStubs
|
||||
|
||||
inline fun foo(x: () -> Unit): String {
|
||||
x()
|
||||
return "OK"
|
||||
}
|
||||
|
||||
fun String.id(s: String = this, vararg xs: Int): String = s
|
||||
|
||||
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:#box(){}kotlin.String"
|
||||
fun box(): String {
|
||||
// CHECK-LABEL: entry
|
||||
// CHECK-NOT: call %struct.ObjHeader* @AllocInstance
|
||||
// CHECK-NOT: alloca
|
||||
return foo("Fail"::id)
|
||||
// CHECK-LABEL: epilogue:
|
||||
}
|
||||
@@ -0,0 +1,372 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// FILECHECK_STAGE: CStubs
|
||||
|
||||
import kotlin.concurrent.*
|
||||
|
||||
// CHECK-AAPCS-LABEL: define i8 @"kfun:#<get-byteGlobal>(){}kotlin.Byte"()
|
||||
// CHECK-DEFAULTABI-LABEL: define signext i8 @"kfun:#<get-byteGlobal>(){}kotlin.Byte"()
|
||||
// CHECK-WINDOWSX64-LABEL: define i8 @"kfun:#<get-byteGlobal>(){}kotlin.Byte"()
|
||||
// CHECK: load atomic i8, i8* @"kvar:byteGlobal#internal" seq_cst
|
||||
// CHECK-LABEL: define void @"kfun:#<set-byteGlobal>(kotlin.Byte){}"(i8
|
||||
// CHECK: store atomic i8 %{{[0-9]+}}, i8* @"kvar:byteGlobal#internal" seq_cst
|
||||
@Volatile var byteGlobal: Byte = 42
|
||||
|
||||
// CHECK-AAPCS-LABEL: define i16 @"kfun:#<get-shortGlobal>(){}kotlin.Short"()
|
||||
// CHECK-DEFAULTABI-LABEL: define signext i16 @"kfun:#<get-shortGlobal>(){}kotlin.Short"()
|
||||
// CHECK-WINDOWSX64-LABEL: define i16 @"kfun:#<get-shortGlobal>(){}kotlin.Short"()
|
||||
// CHECK: load atomic i16, i16* @"kvar:shortGlobal#internal" seq_cst
|
||||
// CHECK-LABEL: define void @"kfun:#<set-shortGlobal>(kotlin.Short){}"(i16
|
||||
// CHECK: store atomic i16 %{{[0-9]+}}, i16* @"kvar:shortGlobal#internal" seq_cst
|
||||
@Volatile var shortGlobal: Short = 42
|
||||
|
||||
// CHECK-LABEL: define i32 @"kfun:#<get-intGlobal>(){}kotlin.Int"()
|
||||
// CHECK: load atomic i32, i32* @"kvar:intGlobal#internal" seq_cst
|
||||
// CHECK-LABEL: define void @"kfun:#<set-intGlobal>(kotlin.Int){}"(i32
|
||||
// CHECK: store atomic i32 %{{[0-9]+}}, i32* @"kvar:intGlobal#internal" seq_cst
|
||||
@Volatile var intGlobal: Int = 42
|
||||
|
||||
// CHECK-LABEL: define i64 @"kfun:#<get-longGlobal>(){}kotlin.Long"()
|
||||
// CHECK: load atomic i64, i64* @"kvar:longGlobal#internal" seq_cst
|
||||
// CHECK-LABEL: define void @"kfun:#<set-longGlobal>(kotlin.Long){}"(i64
|
||||
// CHECK: store atomic i64 %{{[0-9]+}}, i64* @"kvar:longGlobal#internal" seq_cst
|
||||
@Volatile var longGlobal: Long = 42
|
||||
|
||||
// CHECK-AAPCS-LABEL: define i1 @"kfun:#<get-booleanGlobal>(){}kotlin.Boolean"()
|
||||
// CHECK-DEFAULTABI-LABEL: define zeroext i1 @"kfun:#<get-booleanGlobal>(){}kotlin.Boolean"()
|
||||
// CHECK-WINDOWSX64-LABEL: define zeroext i1 @"kfun:#<get-booleanGlobal>(){}kotlin.Boolean"()
|
||||
// CHECK: load atomic i8, i8* @"kvar:booleanGlobal#internal" seq_cst
|
||||
// CHECK-LABEL: define void @"kfun:#<set-booleanGlobal>(kotlin.Boolean){}"(i1
|
||||
// CHECK: store atomic i8 %{{[0-9]+}}, i8* @"kvar:booleanGlobal#internal" seq_cst
|
||||
@Volatile var booleanGlobal: Boolean = true
|
||||
|
||||
// Byte
|
||||
fun byteGlobal_getField() = byteGlobal
|
||||
fun byteGlobal_setField() { byteGlobal = 0 }
|
||||
|
||||
// CHECK-AAPCS-LABEL: define i8 @"kfun:#byteGlobal_getAndSetField(){}kotlin.Byte"()
|
||||
// CHECK-DEFAULTABI-LABEL: define signext i8 @"kfun:#byteGlobal_getAndSetField(){}kotlin.Byte"()
|
||||
// CHECK-WINDOWSX64-LABEL: define i8 @"kfun:#byteGlobal_getAndSetField(){}kotlin.Byte"()
|
||||
// CHECK: atomicrmw xchg i8* @"kvar:byteGlobal#internal", i8 0 seq_cst
|
||||
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
|
||||
fun byteGlobal_getAndSetField() = ::byteGlobal.getAndSetField(0.toByte())
|
||||
|
||||
// CHECK-AAPCS-LABEL: define i8 @"kfun:#byteGlobal_getAndAddField(){}kotlin.Byte"()
|
||||
// CHECK-DEFAULTABI-LABEL: define signext i8 @"kfun:#byteGlobal_getAndAddField(){}kotlin.Byte"()
|
||||
// CHECK-WINDOWSX64-LABEL: define i8 @"kfun:#byteGlobal_getAndAddField(){}kotlin.Byte"()
|
||||
// CHECK: atomicrmw add i8* @"kvar:byteGlobal#internal", i8 0 seq_cst
|
||||
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
|
||||
fun byteGlobal_getAndAddField() = ::byteGlobal.getAndAddField(0.toByte())
|
||||
|
||||
// CHECK-AAPCS-LABEL: define i1 @"kfun:#byteGlobal_compareAndSetField(){}kotlin.Boolean"()
|
||||
// CHECK-DEFAULTABI-LABEL: define zeroext i1 @"kfun:#byteGlobal_compareAndSetField(){}kotlin.Boolean"()
|
||||
// CHECK-WINDOWSX64-LABEL: define zeroext i1 @"kfun:#byteGlobal_compareAndSetField(){}kotlin.Boolean"()
|
||||
// CHECK: cmpxchg i8* @"kvar:byteGlobal#internal", i8 0, i8 1 seq_cst seq_cst
|
||||
// CHECK: extractvalue { i8, i1 } %{{[0-9]+}}, 1
|
||||
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
|
||||
fun byteGlobal_compareAndSetField() = ::byteGlobal.compareAndSetField(0.toByte(), 1.toByte())
|
||||
|
||||
// CHECK-AAPCS-LABEL: define i8 @"kfun:#byteGlobal_compareAndExchangeField(){}kotlin.Byte"()
|
||||
// CHECK-DEFAULTABI-LABEL: define signext i8 @"kfun:#byteGlobal_compareAndExchangeField(){}kotlin.Byte"()
|
||||
// CHECK-WINDOWSX64-LABEL: define i8 @"kfun:#byteGlobal_compareAndExchangeField(){}kotlin.Byte"()
|
||||
// CHECK: cmpxchg i8* @"kvar:byteGlobal#internal", i8 0, i8 1 seq_cst seq_cst
|
||||
// CHECK: extractvalue { i8, i1 } %{{[0-9]+}}, 0
|
||||
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
|
||||
fun byteGlobal_compareAndExchangeField() = ::byteGlobal.compareAndExchangeField(0.toByte(), 1.toByte())
|
||||
|
||||
// Short
|
||||
fun shortGlobal_getField() = shortGlobal
|
||||
fun shortGlobal_setField() { shortGlobal = 0 }
|
||||
|
||||
// CHECK-AAPCS-LABEL: define i16 @"kfun:#shortGlobal_getAndSetField(){}
|
||||
// CHECK-DEFAULTABI-LABEL: define signext i16 @"kfun:#shortGlobal_getAndSetField(){}
|
||||
// CHECK-WINDOWSX64-LABEL: define i16 @"kfun:#shortGlobal_getAndSetField(){}
|
||||
// CHECK: atomicrmw xchg i16* @"kvar:shortGlobal#internal", i16 0 seq_cst
|
||||
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
|
||||
fun shortGlobal_getAndSetField() = ::shortGlobal.getAndSetField(0.toShort())
|
||||
|
||||
// CHECK-AAPCS-LABEL: define i16 @"kfun:#shortGlobal_getAndAddField(){}
|
||||
// CHECK-DEFAULTABI-LABEL: define signext i16 @"kfun:#shortGlobal_getAndAddField(){}
|
||||
// CHECK-WINDOWSX64-LABEL: define i16 @"kfun:#shortGlobal_getAndAddField(){}
|
||||
// CHECK: atomicrmw add i16* @"kvar:shortGlobal#internal", i16 0 seq_cst
|
||||
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
|
||||
fun shortGlobal_getAndAddField() = ::shortGlobal.getAndAddField(0.toShort())
|
||||
|
||||
// CHECK-AAPCS-LABEL: define i1 @"kfun:#shortGlobal_compareAndSetField(){}
|
||||
// CHECK-DEFAULTABI-LABEL: define zeroext i1 @"kfun:#shortGlobal_compareAndSetField(){}
|
||||
// CHECK-WINDOWSX64-LABEL: define zeroext i1 @"kfun:#shortGlobal_compareAndSetField(){}
|
||||
// CHECK: cmpxchg i16* @"kvar:shortGlobal#internal", i16 0, i16 1 seq_cst seq_cst
|
||||
// CHECK: extractvalue { i16, i1 } %{{[0-9]+}}, 1
|
||||
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
|
||||
fun shortGlobal_compareAndSetField() = ::shortGlobal.compareAndSetField(0.toShort(), 1.toShort())
|
||||
|
||||
// CHECK-AAPCS-LABEL: define i16 @"kfun:#shortGlobal_compareAndExchangeField(){}
|
||||
// CHECK-DEFAULTABI-LABEL: define signext i16 @"kfun:#shortGlobal_compareAndExchangeField(){}
|
||||
// CHECK-WINDOWSX64-LABEL: define i16 @"kfun:#shortGlobal_compareAndExchangeField(){}
|
||||
// CHECK: cmpxchg i16* @"kvar:shortGlobal#internal", i16 0, i16 1 seq_cst seq_cst
|
||||
// CHECK: extractvalue { i16, i1 } %{{[0-9]+}}, 0
|
||||
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
|
||||
fun shortGlobal_compareAndExchangeField() = ::shortGlobal.compareAndExchangeField(0.toShort(), 1.toShort())
|
||||
|
||||
// Int
|
||||
fun intGlobal_getField() = intGlobal
|
||||
fun intGlobal_setField() { intGlobal = 0 }
|
||||
|
||||
// CHECK-LABEL: define i32 @"kfun:#intGlobal_getAndSetField(){}
|
||||
// CHECK: atomicrmw xchg i32* @"kvar:intGlobal#internal", i32 0 seq_cst
|
||||
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
|
||||
fun intGlobal_getAndSetField() = ::intGlobal.getAndSetField(0)
|
||||
|
||||
// CHECK-LABEL: define i32 @"kfun:#intGlobal_getAndAddField(){}
|
||||
// CHECK: atomicrmw add i32* @"kvar:intGlobal#internal", i32 0 seq_cst
|
||||
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
|
||||
fun intGlobal_getAndAddField() = ::intGlobal.getAndAddField(0)
|
||||
|
||||
// CHECK-AAPCS-LABEL: define i1 @"kfun:#intGlobal_compareAndSetField(){}
|
||||
// CHECK-DEFAULTABI-LABEL: define zeroext i1 @"kfun:#intGlobal_compareAndSetField(){}
|
||||
// CHECK-WINDOWSX64-LABEL: define zeroext i1 @"kfun:#intGlobal_compareAndSetField(){}
|
||||
// CHECK: cmpxchg i32* @"kvar:intGlobal#internal", i32 0, i32 1 seq_cst seq_cst
|
||||
// CHECK: extractvalue { i32, i1 } %{{[0-9]+}}, 1
|
||||
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
|
||||
fun intGlobal_compareAndSetField() = ::intGlobal.compareAndSetField(0, 1)
|
||||
|
||||
// CHECK-LABEL: define i32 @"kfun:#intGlobal_compareAndExchangeField(){}
|
||||
// CHECK: cmpxchg i32* @"kvar:intGlobal#internal", i32 0, i32 1 seq_cst seq_cst
|
||||
// CHECK: extractvalue { i32, i1 } %{{[0-9]+}}, 0
|
||||
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
|
||||
fun intGlobal_compareAndExchangeField() = ::intGlobal.compareAndExchangeField(0, 1)
|
||||
|
||||
// Long
|
||||
fun longGlobal_getField() = longGlobal
|
||||
fun longGlobal_setField() { longGlobal = 0 }
|
||||
|
||||
// CHECK-LABEL: define i64 @"kfun:#longGlobal_getAndSetField(){}
|
||||
// CHECK: atomicrmw xchg i64* @"kvar:longGlobal#internal", i64 0 seq_cst
|
||||
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
|
||||
fun longGlobal_getAndSetField() = ::longGlobal.getAndSetField(0L)
|
||||
|
||||
// CHECK-LABEL: define i64 @"kfun:#longGlobal_getAndAddField(){}
|
||||
// CHECK: atomicrmw add i64* @"kvar:longGlobal#internal", i64 0 seq_cst
|
||||
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
|
||||
fun longGlobal_getAndAddField() = ::longGlobal.getAndAddField(0L)
|
||||
|
||||
// CHECK-AAPCS-LABEL: define i1 @"kfun:#longGlobal_compareAndSetField(){}
|
||||
// CHECK-DEFAULTABI-LABEL: define zeroext i1 @"kfun:#longGlobal_compareAndSetField(){}
|
||||
// CHECK-WINDOWSX64-LABEL: define zeroext i1 @"kfun:#longGlobal_compareAndSetField(){}
|
||||
// CHECK: cmpxchg i64* @"kvar:longGlobal#internal", i64 0, i64 1 seq_cst seq_cst
|
||||
// CHECK: extractvalue { i64, i1 } %{{[0-9]+}}, 1
|
||||
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
|
||||
fun longGlobal_compareAndSetField() = ::longGlobal.compareAndSetField(0L, 1L)
|
||||
|
||||
// CHECK-LABEL: define i64 @"kfun:#longGlobal_compareAndExchangeField(){}
|
||||
// CHECK: cmpxchg i64* @"kvar:longGlobal#internal", i64 0, i64 1 seq_cst seq_cst
|
||||
// CHECK: extractvalue { i64, i1 } %{{[0-9]+}}, 0
|
||||
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
|
||||
fun longGlobal_compareAndExchangeField() = ::longGlobal.compareAndExchangeField(0L, 1L)
|
||||
|
||||
// Boolean
|
||||
fun booleanGlobal_getField() = booleanGlobal
|
||||
fun booleanGlobal_setField() { booleanGlobal = false }
|
||||
|
||||
// CHECK-AAPCS-LABEL: define i1 @"kfun:#booleanGlobal_getAndSetField(){}kotlin.Boolean"
|
||||
// CHECK-DEFAULTABI-LABEL: define zeroext i1 @"kfun:#booleanGlobal_getAndSetField(){}kotlin.Boolean"
|
||||
// CHECK-WINDOWSX64-LABEL: define zeroext i1 @"kfun:#booleanGlobal_getAndSetField(){}kotlin.Boolean"
|
||||
// CHECK: atomicrmw xchg i8* @"kvar:booleanGlobal#internal", i8 %{{[0-9]+}} seq_cst
|
||||
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
|
||||
fun booleanGlobal_getAndSetField() = ::booleanGlobal.getAndSetField(false)
|
||||
|
||||
// CHECK-AAPCS-LABEL: define i1 @"kfun:#booleanGlobal_compareAndSetField(){}
|
||||
// CHECK-DEFAULTABI-LABEL: define zeroext i1 @"kfun:#booleanGlobal_compareAndSetField(){}
|
||||
// CHECK-WINDOWSX64-LABEL: define zeroext i1 @"kfun:#booleanGlobal_compareAndSetField(){}
|
||||
// CHECK: cmpxchg i8* @"kvar:booleanGlobal#internal", i8 %{{[0-9]+}}, i8 %{{[0-9]+}} seq_cst seq_cst
|
||||
// CHECK: extractvalue { i8, i1 } %{{[0-9]+}}, 1
|
||||
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
|
||||
fun booleanGlobal_compareAndSetField() = ::booleanGlobal.compareAndSetField(false, true)
|
||||
|
||||
// CHECK-AAPCS-LABEL: define i1 @"kfun:#booleanGlobal_compareAndExchangeField(){}
|
||||
// CHECK-DEFAULTABI-LABEL: define zeroext i1 @"kfun:#booleanGlobal_compareAndExchangeField(){}
|
||||
// CHECK-WINDOWSX64-LABEL: define zeroext i1 @"kfun:#booleanGlobal_compareAndExchangeField(){}
|
||||
// CHECK: cmpxchg i8* @"kvar:booleanGlobal#internal", i8 %{{[0-9]+}}, i8 %{{[0-9]+}} seq_cst seq_cst
|
||||
// CHECK: extractvalue { i8, i1 } %{{[0-9]+}}, 0
|
||||
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
|
||||
fun booleanGlobal_compareAndExchangeField() = ::booleanGlobal.compareAndExchangeField(false, true)
|
||||
|
||||
// IntArray
|
||||
val intArr = IntArray(2)
|
||||
|
||||
// CHECK-LABEL: define i32 @"kfun:#intArr_atomicGet(){}kotlin.Int"()
|
||||
// CHECK: call i32* @Kotlin_intArrayGetElementAddress(%struct.ObjHeader* %{{[0-9]+}}, i32 0)
|
||||
// CHECK: load atomic i32, i32* %{{[0-9]+}} seq_cst
|
||||
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
|
||||
fun intArr_atomicGet() = intArr.atomicGet(0)
|
||||
|
||||
// CHECK-LABEL: define void @"kfun:#intArr_atomicSet(){}"()
|
||||
// CHECK: call i32* @Kotlin_intArrayGetElementAddress(%struct.ObjHeader* %{{[0-9]+}}, i32 0)
|
||||
// CHECK: store atomic i32 1, i32* %{{[0-9]+}} seq_cst
|
||||
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
|
||||
fun intArr_atomicSet() = intArr.atomicSet(0, 1)
|
||||
|
||||
// CHECK-LABEL: define i32 @"kfun:#intArr_getAndSet(){}kotlin.Int"()
|
||||
// CHECK: call i32* @Kotlin_intArrayGetElementAddress(%struct.ObjHeader* %{{[0-9]+}}, i32 0)
|
||||
// CHECK: atomicrmw xchg i32* %{{[0-9]+}}, i32 1 seq_cst
|
||||
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
|
||||
fun intArr_getAndSet() = intArr.getAndSet(0, 1)
|
||||
|
||||
// CHECK-LABEL: define i32 @"kfun:#intArr_getAndAdd(){}kotlin.Int"()
|
||||
// CHECK: call i32* @Kotlin_intArrayGetElementAddress(%struct.ObjHeader* %{{[0-9]+}}, i32 0)
|
||||
// CHECK: atomicrmw add i32* %{{[0-9]+}}, i32 1 seq_cst
|
||||
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
|
||||
fun intArr_getAndAdd() = intArr.getAndAdd(0, 1)
|
||||
|
||||
// CHECK-LABEL: define i32 @"kfun:#intArr_compareAndExchange(){}kotlin.Int"()
|
||||
// CHECK: call i32* @Kotlin_intArrayGetElementAddress(%struct.ObjHeader* %{{[0-9]+}}, i32 0)
|
||||
// CHECK: cmpxchg i32* %{{[0-9]+}}, i32 1, i32 2 seq_cst seq_cst
|
||||
// CHECK: extractvalue { i32, i1 } %{{[0-9]+}}, 0
|
||||
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
|
||||
fun intArr_compareAndExchange() = intArr.compareAndExchange(0, 1, 2)
|
||||
|
||||
// CHECK-AAPCS-LABEL: define i1 @"kfun:#intArr_compareAndSet(){}kotlin.Boolean"()
|
||||
// CHECK-DEFAULTABI-LABEL: define zeroext i1 @"kfun:#intArr_compareAndSet(){}kotlin.Boolean"()
|
||||
// CHECK-WINDOWSX64-LABEL: define zeroext i1 @"kfun:#intArr_compareAndSet(){}kotlin.Boolean"()
|
||||
// CHECK: call i32* @Kotlin_intArrayGetElementAddress(%struct.ObjHeader* %{{[0-9]+}}, i32 0)
|
||||
// CHECK: cmpxchg i32* %{{[0-9]+}}, i32 1, i32 2 seq_cst seq_cst
|
||||
// CHECK: extractvalue { i32, i1 } %{{[0-9]+}}, 1
|
||||
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
|
||||
fun intArr_compareAndSet() = intArr.compareAndSet(0, 1, 2)
|
||||
|
||||
// LongArray
|
||||
val longArr = LongArray(2)
|
||||
|
||||
// CHECK-LABEL: define i64 @"kfun:#longArr_atomicGet(){}kotlin.Long"()
|
||||
// CHECK: call i64* @Kotlin_longArrayGetElementAddress(%struct.ObjHeader* %{{[0-9]+}}, i32 0)
|
||||
// CHECK: load atomic i64, i64* %{{[0-9]+}} seq_cst
|
||||
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
|
||||
fun longArr_atomicGet() = longArr.atomicGet(0)
|
||||
|
||||
// CHECK-LABEL: define void @"kfun:#longArr_atomicSet(){}"()
|
||||
// CHECK: call i64* @Kotlin_longArrayGetElementAddress(%struct.ObjHeader* %{{[0-9]+}}, i32 0)
|
||||
// CHECK: store atomic i64 1, i64* %{{[0-9]+}} seq_cst
|
||||
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
|
||||
fun longArr_atomicSet() = longArr.atomicSet(0, 1L)
|
||||
|
||||
// CHECK-LABEL: define i64 @"kfun:#longArr_getAndSet(){}kotlin.Long"()
|
||||
// CHECK: call i64* @Kotlin_longArrayGetElementAddress(%struct.ObjHeader* %{{[0-9]+}}, i32 0)
|
||||
// CHECK: atomicrmw xchg i64* %{{[0-9]+}}, i64 1 seq_cst
|
||||
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
|
||||
fun longArr_getAndSet() = longArr.getAndSet(0, 1L)
|
||||
|
||||
// CHECK-LABEL: define i64 @"kfun:#longArr_getAndAdd(){}kotlin.Long"()
|
||||
// CHECK: call i64* @Kotlin_longArrayGetElementAddress(%struct.ObjHeader* %{{[0-9]+}}, i32 0)
|
||||
// CHECK: atomicrmw add i64* %{{[0-9]+}}, i64 1 seq_cst
|
||||
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
|
||||
fun longArr_getAndAdd() = longArr.getAndAdd(0, 1L)
|
||||
|
||||
// CHECK-LABEL: define i64 @"kfun:#longArr_compareAndExchange(){}kotlin.Long"()
|
||||
// CHECK: call i64* @Kotlin_longArrayGetElementAddress(%struct.ObjHeader* %{{[0-9]+}}, i32 0)
|
||||
// CHECK: cmpxchg i64* %{{[0-9]+}}, i64 1, i64 2 seq_cst seq_cst
|
||||
// CHECK: extractvalue { i64, i1 } %{{[0-9]+}}, 0
|
||||
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
|
||||
fun longArr_compareAndExchange() = longArr.compareAndExchange(0, 1L, 2L)
|
||||
|
||||
// CHECK-AAPCS-LABEL: define i1 @"kfun:#longArr_compareAndSet(){}kotlin.Boolean"()
|
||||
// CHECK-DEFAULTABI-LABEL: define zeroext i1 @"kfun:#longArr_compareAndSet(){}kotlin.Boolean"()
|
||||
// CHECK-WINDOWSX64-LABEL: define zeroext i1 @"kfun:#longArr_compareAndSet(){}kotlin.Boolean"()
|
||||
// CHECK: call i64* @Kotlin_longArrayGetElementAddress(%struct.ObjHeader* %{{[0-9]+}}, i32 0)
|
||||
// CHECK: cmpxchg i64* %{{[0-9]+}}, i64 1, i64 2 seq_cst seq_cst
|
||||
// CHECK: extractvalue { i64, i1 } %{{[0-9]+}}, 1
|
||||
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
|
||||
fun longArr_compareAndSet() = longArr.compareAndSet(0, 1L, 2L)
|
||||
|
||||
// Array<T>
|
||||
val refArr = arrayOfNulls<String?>(2)
|
||||
|
||||
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:#refArr_atomicGet(){}kotlin.String?"
|
||||
// CHECK: call %struct.ObjHeader** @Kotlin_arrayGetElementAddress(%struct.ObjHeader* %{{[0-9]+}}, i32 0)
|
||||
// CHECK: load atomic %struct.ObjHeader*, %struct.ObjHeader** %{{[0-9]+}} seq_cst
|
||||
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
|
||||
fun refArr_atomicGet() = refArr.atomicGet(0)
|
||||
|
||||
// CHECK-LABEL: define void @"kfun:#refArr_atomicSet(){}"()
|
||||
// CHECK: call %struct.ObjHeader** @Kotlin_arrayGetElementAddress(%struct.ObjHeader* %{{[0-9]+}}, i32 0)
|
||||
// CHECK: call void @UpdateVolatileHeapRef(%struct.ObjHeader** %{{[0-9]+}}, %struct.ObjHeader* null)
|
||||
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
|
||||
fun refArr_atomicSet() = refArr.atomicSet(0, null)
|
||||
|
||||
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:#refArr_getAndSet(){}kotlin.String?"
|
||||
// CHECK: call %struct.ObjHeader** @Kotlin_arrayGetElementAddress(%struct.ObjHeader* %{{[0-9]+}}, i32 0)
|
||||
// CHECK: call %struct.ObjHeader* @GetAndSetVolatileHeapRef(%struct.ObjHeader** %{{[0-9]+}}, %struct.ObjHeader* null, %struct.ObjHeader** %{{[0-9]+}})
|
||||
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
|
||||
fun refArr_getAndSet() = refArr.getAndSet(0, null)
|
||||
|
||||
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:#refArr_compareAndExchange(){}kotlin.String?"
|
||||
// CHECK: call %struct.ObjHeader** @Kotlin_arrayGetElementAddress(%struct.ObjHeader* %{{[0-9]+}}, i32 0)
|
||||
// CHECK: call %struct.ObjHeader* @CompareAndSwapVolatileHeapRef(%struct.ObjHeader** %{{[0-9]+}}, %struct.ObjHeader* null, %struct.ObjHeader* null, %struct.ObjHeader** %{{[0-9]+}})
|
||||
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
|
||||
fun refArr_compareAndExchange() = refArr.compareAndExchange(0, null, null)
|
||||
|
||||
// CHECK-AAPCS-LABEL: define i1 @"kfun:#refArr_compareAndSet(){}kotlin.Boolean"()
|
||||
// CHECK-DEFAULTABI-LABEL: define zeroext i1 @"kfun:#refArr_compareAndSet(){}kotlin.Boolean"()
|
||||
// CHECK-WINDOWSX64-LABEL: define zeroext i1 @"kfun:#refArr_compareAndSet(){}kotlin.Boolean"()
|
||||
// CHECK: call %struct.ObjHeader** @Kotlin_arrayGetElementAddress(%struct.ObjHeader* %{{[0-9]+}}, i32 0)
|
||||
// CHECK-AAPCS: call i1 @CompareAndSetVolatileHeapRef(%struct.ObjHeader** %{{[0-9]+}}, %struct.ObjHeader* null, %struct.ObjHeader* null)
|
||||
// CHECK-DEFAULTABI: call zeroext i1 @CompareAndSetVolatileHeapRef(%struct.ObjHeader** %{{[0-9]+}}, %struct.ObjHeader* null, %struct.ObjHeader* null)
|
||||
// CHECK-WINDOWSX64: call zeroext i1 @CompareAndSetVolatileHeapRef(%struct.ObjHeader** %{{[0-9]+}}, %struct.ObjHeader* null, %struct.ObjHeader* null)
|
||||
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
|
||||
fun refArr_compareAndSet() = refArr.compareAndSet(0, null, null)
|
||||
|
||||
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:#box(){}kotlin.String"
|
||||
fun box(): String {
|
||||
byteGlobal_getField()
|
||||
byteGlobal_setField()
|
||||
byteGlobal_getAndSetField()
|
||||
byteGlobal_getAndAddField()
|
||||
byteGlobal_compareAndSetField()
|
||||
byteGlobal_compareAndExchangeField()
|
||||
|
||||
shortGlobal_getField()
|
||||
shortGlobal_setField()
|
||||
shortGlobal_getAndSetField()
|
||||
shortGlobal_getAndAddField()
|
||||
shortGlobal_compareAndSetField()
|
||||
shortGlobal_compareAndExchangeField()
|
||||
|
||||
intGlobal_getField()
|
||||
intGlobal_setField()
|
||||
intGlobal_getAndSetField()
|
||||
intGlobal_getAndAddField()
|
||||
intGlobal_compareAndSetField()
|
||||
intGlobal_compareAndExchangeField()
|
||||
|
||||
longGlobal_getField()
|
||||
longGlobal_setField()
|
||||
longGlobal_getAndSetField()
|
||||
longGlobal_getAndAddField()
|
||||
longGlobal_compareAndSetField()
|
||||
longGlobal_compareAndExchangeField()
|
||||
|
||||
booleanGlobal_getField()
|
||||
booleanGlobal_setField()
|
||||
booleanGlobal_getAndSetField()
|
||||
booleanGlobal_compareAndSetField()
|
||||
booleanGlobal_compareAndExchangeField()
|
||||
|
||||
intArr_atomicGet()
|
||||
intArr_atomicSet()
|
||||
intArr_getAndSet()
|
||||
intArr_getAndAdd()
|
||||
intArr_compareAndSet()
|
||||
intArr_compareAndExchange()
|
||||
|
||||
longArr_atomicGet()
|
||||
longArr_atomicSet()
|
||||
longArr_getAndSet()
|
||||
longArr_getAndAdd()
|
||||
longArr_compareAndSet()
|
||||
longArr_compareAndExchange()
|
||||
|
||||
refArr_atomicGet()
|
||||
refArr_atomicSet()
|
||||
refArr_getAndSet()
|
||||
refArr_compareAndSet()
|
||||
refArr_compareAndExchange()
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,338 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// FILECHECK_STAGE: CStubs
|
||||
|
||||
// CHECK-LABEL: define void @"kfun:#forEachIndicies(){}"()
|
||||
fun forEachIndicies() {
|
||||
val array = Array(10) { 0 }
|
||||
|
||||
// CHECK: {{^}}do_while_loop{{.*}}:
|
||||
for (i in array.indices) {
|
||||
// CHECK: {{call|invoke}} void @Kotlin_Array_set_without_BoundCheck
|
||||
array[i] = 6
|
||||
}
|
||||
}
|
||||
// CHECK-LABEL: {{^}}epilogue:
|
||||
|
||||
// CHECK-LABEL: define void @"kfun:#forUntilSize(){}"()
|
||||
fun forUntilSize() {
|
||||
val array = Array(10) { 0L }
|
||||
// CHECK: {{^}}do_while_loop{{.*}}:
|
||||
for (i in 0 until array.size) {
|
||||
// CHECK: {{call|invoke}} void @Kotlin_Array_set_without_BoundCheck
|
||||
array[i] = 6
|
||||
}
|
||||
}
|
||||
// CHECK-LABEL: {{^}}epilogue:
|
||||
|
||||
// CHECK-LABEL: define void @"kfun:#forRangeUntilSize(){}"()
|
||||
@ExperimentalStdlibApi
|
||||
fun forRangeUntilSize() {
|
||||
val array = Array(10) { 0L }
|
||||
// CHECK: {{^}}do_while_loop{{.*}}:
|
||||
for (i in 0..<array.size) {
|
||||
// CHECK: {{call|invoke}} void @Kotlin_Array_set_without_BoundCheck
|
||||
array[i] = 6
|
||||
}
|
||||
}
|
||||
// CHECK-LABEL: {{^}}epilogue:
|
||||
|
||||
// CHECK-LABEL: define void @"kfun:#forDownToSize(){}"()
|
||||
fun forDownToSize() {
|
||||
val array = Array(10) { 0L }
|
||||
|
||||
// CHECK: {{^}}do_while_loop{{.*}}:
|
||||
for (i in array.size - 1 downTo 0) {
|
||||
// CHECK: {{call|invoke}} void @Kotlin_Array_set_without_BoundCheck
|
||||
array[i] = 6
|
||||
}
|
||||
|
||||
// CHECK: {{^}}do_while_loop{{.*}}:
|
||||
for (j in array.size - 3 downTo 0) {
|
||||
// CHECK: {{call|invoke}} void @Kotlin_Array_set_without_BoundCheck
|
||||
array[j] = 6
|
||||
}
|
||||
}
|
||||
// CHECK-LABEL: {{^}}epilogue:
|
||||
|
||||
// CHECK-LABEL: define void @"kfun:#forRangeToSize(){}"()
|
||||
fun forRangeToSize() {
|
||||
val array = Array(10) { 0L }
|
||||
|
||||
// CHECK: {{^}}do_while_loop{{.*}}:
|
||||
for (i in 0..array.size - 1) {
|
||||
// CHECK: {{call|invoke}} void @Kotlin_Array_set_without_BoundCheck
|
||||
array[i] = 6
|
||||
}
|
||||
|
||||
val length = array.size - 1
|
||||
|
||||
// CHECK: {{^}}do_while_loop{{.*}}:
|
||||
for (j in 0..length) {
|
||||
// CHECK: {{call|invoke}} void @Kotlin_Array_set_without_BoundCheck
|
||||
array[j] = 6
|
||||
}
|
||||
}
|
||||
// CHECK-LABEL: {{^}}epilogue:
|
||||
|
||||
// CHECK-LABEL: define void @"kfun:#forRangeToWithStep(){}"()
|
||||
fun forRangeToWithStep() {
|
||||
val array = Array(10) { 0L }
|
||||
|
||||
// CHECK: {{^}}do_while_loop{{.*}}:
|
||||
for (i in 0..array.size - 1 step 2) {
|
||||
// CHECK: {{call|invoke}} void @Kotlin_Array_set_without_BoundCheck
|
||||
array[i] = 6
|
||||
}
|
||||
}
|
||||
// CHECK-LABEL: {{^}}epilogue:
|
||||
|
||||
// CHECK-LABEL: define void @"kfun:#forUntilWithStep(){}"()
|
||||
fun forUntilWithStep() {
|
||||
val array = CharArray(10) { '0' }
|
||||
// CHECK: {{^}}do_while_loop{{.*}}:
|
||||
for (i in 0 until array.size step 2) {
|
||||
// CHECK: {{call|invoke}} void @Kotlin_CharArray_set_without_BoundCheck
|
||||
array[i] = '6'
|
||||
}
|
||||
}
|
||||
// CHECK-LABEL: {{^}}epilogue:
|
||||
|
||||
// CHECK-LABEL: define void @"kfun:#forRangeUntilWithStep(){}"()
|
||||
@ExperimentalStdlibApi
|
||||
fun forRangeUntilWithStep() {
|
||||
val array = CharArray(10) { '0' }
|
||||
// CHECK: {{^}}do_while_loop{{.*}}:
|
||||
for (i in 0..<array.size step 2) {
|
||||
// CHECK: {{call|invoke}} void @Kotlin_CharArray_set_without_BoundCheck
|
||||
array[i] = '6'
|
||||
}
|
||||
}
|
||||
// CHECK-LABEL: {{^}}epilogue:
|
||||
|
||||
// CHECK-LABEL: define void @"kfun:#forDownToWithStep(){}"()
|
||||
fun forDownToWithStep() {
|
||||
val array = UIntArray(10) { 0U }
|
||||
// CHECK: {{^}}do_while_loop{{.*}}:
|
||||
for (i in array.size - 1 downTo 0 step 2) {
|
||||
// CHECK: {{call|invoke}} void @Kotlin_IntArray_set_without_BoundCheck
|
||||
array[i] = 6U
|
||||
}
|
||||
}
|
||||
// CHECK-LABEL: {{^}}epilogue:
|
||||
|
||||
// CHECK-LABEL: define void @"kfun:#forIndiciesWithStep(){}"()
|
||||
fun forIndiciesWithStep() {
|
||||
val array = Array(10) { 0L }
|
||||
// CHECK: {{^}}do_while_loop{{.*}}:
|
||||
for (i in array.indices step 2) {
|
||||
// CHECK: {{call|invoke}} void @Kotlin_Array_set_without_BoundCheck
|
||||
array[i] = 6
|
||||
}
|
||||
}
|
||||
// CHECK-LABEL: {{^}}epilogue:
|
||||
|
||||
// CHECK-LABEL: define void @"kfun:#forWithIndex(){}"()
|
||||
fun forWithIndex() {
|
||||
val array = Array(10) { 100 }
|
||||
|
||||
// CHECK: {{^}}while_loop{{.*}}:
|
||||
for ((index, value) in array.withIndex()) {
|
||||
// CHECK: {{call|invoke}} %struct.ObjHeader* @Kotlin_Array_get_without_BoundCheck
|
||||
array[index] = 6
|
||||
}
|
||||
}
|
||||
// CHECK-LABEL: {{^}}epilogue:
|
||||
|
||||
// CHECK-LABEL: define void @"kfun:#forReversed(){}"()
|
||||
fun forReversed() {
|
||||
val array = Array(10) { 100 }
|
||||
// CHECK: {{^}}do_while_loop{{.*}}:
|
||||
for (i in (0..array.size-1).reversed()) {
|
||||
// CHECK: {{call|invoke}} void @Kotlin_Array_set_without_BoundCheck
|
||||
array[i] = 6
|
||||
}
|
||||
}
|
||||
// CHECK-LABEL: {{^}}epilogue:
|
||||
|
||||
// CHECK-LABEL: define void @"kfun:#forRangeUntilReversed(){}"()
|
||||
@ExperimentalStdlibApi
|
||||
fun forRangeUntilReversed() {
|
||||
val array = Array(10) { 100 }
|
||||
// CHECK: {{^}}do_while_loop{{.*}}:
|
||||
for (i in (0..<array.size).reversed()) {
|
||||
// CHECK: {{call|invoke}} void @Kotlin_Array_set_without_BoundCheck
|
||||
array[i] = 6
|
||||
}
|
||||
}
|
||||
// CHECK-LABEL: {{^}}epilogue:
|
||||
|
||||
fun foo(a: Int, b : Int): Int = a + b * 2
|
||||
|
||||
// CHECK-LABEL: define void @"kfun:#forEachCall(){}"()
|
||||
fun forEachCall() {
|
||||
val array = Array(10) { 100 }
|
||||
var sum = 0
|
||||
// CHECK: {{^}}while_loop{{.*}}:
|
||||
array.forEach {
|
||||
// CHECK: {{call|invoke}} %struct.ObjHeader* @Kotlin_Array_get_without_BoundCheck
|
||||
sum += it
|
||||
}
|
||||
}
|
||||
// CHECK-LABEL: {{^}}epilogue:
|
||||
|
||||
// CHECK-LABEL: define void @"kfun:#forLoop(){}"()
|
||||
fun forLoop() {
|
||||
val array = Array(10) { 100 }
|
||||
var sum = 0
|
||||
// CHECK: {{^}}while_loop{{.*}}:
|
||||
for (it in array) {
|
||||
// CHECK: {{call|invoke}} %struct.ObjHeader* @Kotlin_Array_get_without_BoundCheck
|
||||
sum += it
|
||||
}
|
||||
}
|
||||
// CHECK-LABEL: {{^}}epilogue:
|
||||
|
||||
// CHECK-LABEL: define void @"kfun:#innerLoop(){}"()
|
||||
fun innerLoop() {
|
||||
val array = Array(10) { 100 }
|
||||
val array1 = Array(3) { 0 }
|
||||
|
||||
// CHECK: {{^}}do_while_loop{{.*}}:
|
||||
for (i in 0 until array.size) {
|
||||
// CHECK-DAG: {{call|invoke}} %struct.ObjHeader* @Kotlin_Array_get_without_BoundCheck
|
||||
array[i] = 7
|
||||
// CHECK-DAG: {{call|invoke}} void @Kotlin_Array_set_without_BoundCheck
|
||||
// CHECK-DAG: {{call|invoke}} void @Kotlin_Array_set_without_BoundCheck
|
||||
for (j in 0 until array1.size) {
|
||||
array1[j] = array[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
// CHECK-LABEL: {{^}}epilogue:
|
||||
|
||||
// CHECK-LABEL: define void @"kfun:#argsInFunctionCall(){}"()
|
||||
fun argsInFunctionCall() {
|
||||
val array = Array(10) { 100 }
|
||||
|
||||
val size = array.size - 1
|
||||
val size1 = size
|
||||
|
||||
// CHECK: {{^}}do_while_loop{{.*}}:
|
||||
for (i in 0..size1) {
|
||||
// CHECK: {{call|invoke}} %struct.ObjHeader* @Kotlin_Array_get_without_BoundCheck
|
||||
// CHECK: {{call|invoke}} %struct.ObjHeader* @Kotlin_Array_get_without_BoundCheck
|
||||
// CHECK: {{call|invoke}} i32 @"kfun:#foo(kotlin.Int;kotlin.Int){}kotlin.Int"
|
||||
foo(array[i], array[i])
|
||||
}
|
||||
}
|
||||
// CHECK-LABEL: {{^}}epilogue:
|
||||
|
||||
// CHECK-LABEL: define void @"kfun:#smallLoop(){}"()
|
||||
fun smallLoop() {
|
||||
val array = Array(10) { 100 }
|
||||
|
||||
// CHECK: {{^}}do_while_loop{{.*}}:
|
||||
for (i in 0..array.size - 2) {
|
||||
// CHECK: {{call|invoke}} %struct.ObjHeader* @Kotlin_Array_get_without_BoundCheck
|
||||
array[i+1] = array[i]
|
||||
}
|
||||
}
|
||||
// CHECK-LABEL: {{^}}epilogue:
|
||||
|
||||
object TopLevelObject {
|
||||
val array = Array(10) { 100 }
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define void @"kfun:#topLevelObject(){}"()
|
||||
fun topLevelObject() {
|
||||
// CHECK: {{^}}do_while_loop{{.*}}:
|
||||
for (i in 0 until TopLevelObject.array.size) {
|
||||
// CHECK: {{call|invoke}} void @Kotlin_Array_set_without_BoundCheck
|
||||
TopLevelObject.array[i] = 6
|
||||
}
|
||||
}
|
||||
// CHECK-LABEL: {{^}}epilogue:
|
||||
|
||||
val array = Array(10) { 100 }
|
||||
|
||||
// CHECK-LABEL: define void @"kfun:#topLevelProperty(){}"()
|
||||
fun topLevelProperty() {
|
||||
// CHECK: {{^}}do_while_loop{{.*}}:
|
||||
for (i in 0..array.size - 2) {
|
||||
// CHECK: {{call|invoke}} void @Kotlin_Array_set_without_BoundCheck
|
||||
array[i] = 6
|
||||
}
|
||||
}
|
||||
// CHECK-LABEL: {{^}}epilogue:
|
||||
|
||||
open class Base() {
|
||||
open val array = Array(10) { 100 }
|
||||
}
|
||||
|
||||
class Child() : Base()
|
||||
|
||||
// CHECK-LABEL: define void @"kfun:#childClassWithFakeOverride(){}"()
|
||||
fun childClassWithFakeOverride() {
|
||||
val child = Child()
|
||||
// CHECK: {{^}}do_while_loop{{.*}}:
|
||||
for (i in 0..child.array.size - 1) {
|
||||
// CHECK: {{call|invoke}} void @Kotlin_Array_set_without_BoundCheck
|
||||
child.array[i] = 6
|
||||
}
|
||||
}
|
||||
// CHECK-LABEL: {{^}}epilogue:
|
||||
|
||||
class First {
|
||||
val child = Child()
|
||||
}
|
||||
|
||||
class Second{
|
||||
val first = First()
|
||||
}
|
||||
|
||||
class Third {
|
||||
val second = Second()
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define void @"kfun:#chainedReceivers(){}"()
|
||||
fun chainedReceivers() {
|
||||
val obj = Third()
|
||||
val obj1 = obj
|
||||
val obj2 = obj1
|
||||
|
||||
// CHECK: {{^}}do_while_loop{{.*}}:
|
||||
for (i in 0 until obj1.second.first.child.array.size) {
|
||||
// CHECK: {{call|invoke}} void @Kotlin_Array_set_without_BoundCheck
|
||||
obj2.second.first.child.array[i] = 6
|
||||
}
|
||||
}
|
||||
// CHECK-LABEL: {{^}}epilogue:
|
||||
|
||||
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:#box(){}kotlin.String"
|
||||
@ExperimentalStdlibApi
|
||||
fun box(): String {
|
||||
forEachIndicies()
|
||||
forUntilSize()
|
||||
forRangeUntilSize()
|
||||
forDownToSize()
|
||||
forRangeToSize()
|
||||
forRangeToWithStep()
|
||||
forUntilWithStep()
|
||||
forRangeUntilWithStep()
|
||||
forDownToWithStep()
|
||||
forIndiciesWithStep()
|
||||
forWithIndex()
|
||||
forReversed()
|
||||
forRangeUntilReversed()
|
||||
forEachCall()
|
||||
forLoop()
|
||||
innerLoop()
|
||||
argsInFunctionCall()
|
||||
smallLoop()
|
||||
topLevelObject()
|
||||
topLevelProperty()
|
||||
childClassWithFakeOverride()
|
||||
chainedReceivers()
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// DISABLE_NATIVE: isAppleTarget=false
|
||||
// FILECHECK_STAGE: CStubs
|
||||
|
||||
// MODULE: cinterop
|
||||
// FILE: direct.def
|
||||
language = Objective-C
|
||||
headers = direct.h
|
||||
headerFilter = direct.h
|
||||
|
||||
// FILE: direct.h
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface CallingConventions : NSObject
|
||||
|
||||
+ (uint64_t)regular:(uint64_t)arg;
|
||||
- (uint64_t)regular:(uint64_t)arg;
|
||||
|
||||
+ (uint64_t)direct:(uint64_t)arg __attribute__((objc_direct));
|
||||
- (uint64_t)direct:(uint64_t)arg __attribute__((objc_direct));
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
// FILE: direct.m
|
||||
#import "direct.h"
|
||||
|
||||
#define TEST_METHOD_IMPL(NAME) (uint64_t)NAME:(uint64_t)arg { return arg; }
|
||||
|
||||
@implementation CallingConventions : NSObject
|
||||
|
||||
+ TEST_METHOD_IMPL(regular);
|
||||
- TEST_METHOD_IMPL(regular);
|
||||
|
||||
+ TEST_METHOD_IMPL(direct);
|
||||
- TEST_METHOD_IMPL(direct);
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
@file:Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
|
||||
import kotlin.native.Retain
|
||||
import direct.*
|
||||
|
||||
// KT-54610
|
||||
fun box(): String {
|
||||
callDirect()
|
||||
callRegular()
|
||||
return "OK"
|
||||
}
|
||||
|
||||
@Retain
|
||||
//CHECK-LABEL: define i64 @"kfun:#callDirect(){}kotlin.ULong"()
|
||||
fun callDirect(): ULong {
|
||||
val cc = CallingConventions()
|
||||
//CHECK: invoke i64 @_{{[a-zA-Z0-9]+}}_knbridge{{[0-9]+}}(i8* %{{[0-9]+}}, i64 42)
|
||||
return cc.direct(42uL)
|
||||
}
|
||||
|
||||
@Retain
|
||||
//CHECK-LABEL: define i64 @"kfun:#callRegular(){}kotlin.ULong"()
|
||||
fun callRegular(): ULong {
|
||||
val cc = CallingConventions()
|
||||
//CHECK: invoke i64 @_{{[a-zA-Z0-9]+}}_knbridge{{[0-9]+}}(i8* %{{[0-9]+}}, i8* %{{[0-9]+}}, i64 42)
|
||||
return cc.regular(42uL)
|
||||
}
|
||||
+168
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use
|
||||
* of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// FILECHECK_STAGE: CStubs
|
||||
// MODULE: cinterop
|
||||
// FILE: signext_zeroext_interop_input.def
|
||||
---
|
||||
char char_id(char c) {
|
||||
return c;
|
||||
}
|
||||
|
||||
unsigned char unsigned_char_id(unsigned char c) {
|
||||
return c;
|
||||
}
|
||||
|
||||
short short_id(short s) {
|
||||
return s;
|
||||
}
|
||||
|
||||
unsigned short unsigned_short_id(unsigned short s) {
|
||||
return s;
|
||||
}
|
||||
|
||||
int callbackUser(int (*fn)(int, short)) {
|
||||
return fn(5,5);
|
||||
}
|
||||
|
||||
// MODULE: main(cinterop)
|
||||
// FILE: main.kt
|
||||
|
||||
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
|
||||
|
||||
import signext_zeroext_interop_input.*
|
||||
import kotlinx.cinterop.*
|
||||
|
||||
// CHECK-DEFAULTABI-CACHE_NO: declare zeroext i1 @Kotlin_Char_isHighSurrogate(i16 zeroext){{.*}}
|
||||
// CHECK-AAPCS-CACHE_NO: declare i1 @Kotlin_Char_isHighSurrogate(i16)
|
||||
// CHECK-WINDOWSX64-CACHE_NO: declare zeroext i1 @Kotlin_Char_isHighSurrogate(i16)
|
||||
|
||||
// Check that we pass attributes to functions imported from runtime.
|
||||
// CHECK-LABEL: void @"kfun:#checkRuntimeFunctionImport(){}"()
|
||||
fun checkRuntimeFunctionImport() {
|
||||
// CHECK-DEFAULTABI: call zeroext i1 @Kotlin_Char_isHighSurrogate(i16 zeroext {{.*}})
|
||||
// CHECK-AAPCS: call i1 @Kotlin_Char_isHighSurrogate(i16 {{.*}})
|
||||
// CHECK-WINDOWSX64: call zeroext i1 @Kotlin_Char_isHighSurrogate(i16 {{.*}})
|
||||
'c'.isHighSurrogate()
|
||||
// CHECK-DEFAULTABI: call zeroext i1 @Kotlin_Float_isNaN(float {{.*}}
|
||||
// CHECK-AAPCS: call i1 @Kotlin_Float_isNaN(float {{.*}}
|
||||
// CHECK-WINDOWSX64: call zeroext i1 @Kotlin_Float_isNaN(float {{.*}}
|
||||
0.0f.isNaN()
|
||||
}
|
||||
|
||||
// CHECK-LABEL: void @"kfun:#checkDirectInterop(){}"()
|
||||
// CHECK-LABEL-AAPCS: void @"kfun:#checkDirectInterop(){}"()
|
||||
// CHECK-LABEL-WINDOWSX64: void @"kfun:#checkDirectInterop(){}"()
|
||||
fun checkDirectInterop() {
|
||||
// compiler generates quite lovely names for bridges
|
||||
// (e.g. `_66696c65636865636b5f7369676e6578745f7a65726f6578745f696e7465726f70_knbridge0`),
|
||||
// so we don't check exact function names here.
|
||||
// CHECK-DEFAULTABI: invoke signext i8 [[CHAR_ID_BRIDGE:@_.*_knbridge[0-9]+]](i8 signext {{.*}})
|
||||
// CHECK-AAPCS: invoke i8 [[CHAR_ID_BRIDGE:@_.*_knbridge[0-9]+]](i8 {{.*}})
|
||||
// CHECK-WINDOWSX64: invoke i8 [[CHAR_ID_BRIDGE:@_.*_knbridge[0-9]+]](i8 {{.*}})
|
||||
char_id(0.toByte())
|
||||
// CHECK-DEFAULTABI: invoke zeroext i8 [[UNSIGNED_CHAR_ID_BRIDGE:@_.*_knbridge[0-9]+]](i8 zeroext {{.*}})
|
||||
// CHECK-AAPCS: invoke i8 [[UNSIGNED_CHAR_ID_BRIDGE:@_.*_knbridge[0-9]+]](i8 {{.*}})
|
||||
// CHECK-WINDOWSX64: invoke i8 [[UNSIGNED_CHAR_ID_BRIDGE:@_.*_knbridge[0-9]+]](i8 {{.*}})
|
||||
unsigned_char_id(0.toUByte())
|
||||
// CHECK-DEFAULTABI: invoke signext i16 [[SHORT_ID_BRIDGE:@_.*_knbridge[0-9]+]](i16 signext {{.*}})
|
||||
// CHECK-AAPCS: invoke i16 [[SHORT_ID_BRIDGE:@_.*_knbridge[0-9]+]](i16 {{.*}})
|
||||
// CHECK-WINDOWSX64: invoke i16 [[SHORT_ID_BRIDGE:@_.*_knbridge[0-9]+]](i16 {{.*}})
|
||||
short_id(0.toShort())
|
||||
// CHECK-DEFAULTABI: invoke zeroext i16 [[UNSIGNED_SHORT_ID_BRIDGE:@_.*_knbridge[0-9]+]](i16 zeroext {{.*}})
|
||||
// CHECK-AAPCS: invoke i16 [[UNSIGNED_SHORT_ID_BRIDGE:@_.*_knbridge[0-9]+]](i16 {{.*}})
|
||||
// CHECK-WINDOWSX64: invoke i16 [[UNSIGNED_SHORT_ID_BRIDGE:@_.*_knbridge[0-9]+]](i16 {{.*}})
|
||||
unsigned_short_id(0.toUShort())
|
||||
// CHECK-DEFAULTABI: invoke i32 [[CALLBACK_USER_BRIDGE:@_.*_knbridge[0-9]+]](i8* bitcast (i32 (i32, i16)* [[STATIC_C_FUNCTION_BRIDGE:@_.*_kncfun[0-9]+]] to i8*))
|
||||
// CHECK-AAPCS: invoke i32 [[CALLBACK_USER_BRIDGE:@_.*_knbridge[0-9]+]](i8* bitcast (i32 (i32, i16)* [[STATIC_C_FUNCTION_BRIDGE:@_.*_kncfun[0-9]+]] to i8*))
|
||||
// CHECK-WINDOWSX64: invoke i32 [[CALLBACK_USER_BRIDGE:@_.*_knbridge[0-9]+]](i8* bitcast (i32 (i32, i16)* [[STATIC_C_FUNCTION_BRIDGE:@_.*_kncfun[0-9]+]] to i8*))
|
||||
callbackUser(staticCFunction { int: Int, short: Short -> int + short })
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:#box(){}kotlin.String"
|
||||
fun box(): String {
|
||||
checkRuntimeFunctionImport()
|
||||
checkDirectInterop()
|
||||
return "OK"
|
||||
}
|
||||
|
||||
// CHECK-DEFAULTABI-CACHE_STATIC_ONLY_DIST: declare zeroext i1 @Kotlin_Char_isHighSurrogate(i16 zeroext){{.*}}
|
||||
// CHECK-AAPCS-CACHE_STATIC_ONLY_DIST: declare i1 @Kotlin_Char_isHighSurrogate(i16)
|
||||
// CHECK-WINDOWSX64-CACHE_STATIC_ONLY_DIST: declare zeroext i1 @Kotlin_Char_isHighSurrogate(i16)
|
||||
|
||||
// CHECK-DEFAULTABI: signext i8 [[CHAR_ID_BRIDGE]](i8 signext %0)
|
||||
// CHECK-DEFAULTABI: [[CHAR_ID_PTR:%[0-9]+]] = load i8 (i8)*, i8 (i8)** @{{.*char_id}}
|
||||
// CHECK-DEFAULTABI: call signext i8 [[CHAR_ID_PTR]](i8 signext %0)
|
||||
|
||||
// CHECK-AAPCS: i8 [[CHAR_ID_BRIDGE]](i8 %0)
|
||||
// CHECK-AAPCS: [[CHAR_ID_PTR:%[0-9]+]] = load i8 (i8)*, i8 (i8)** @{{.*char_id}}
|
||||
// CHECK-AAPCS: call i8 [[CHAR_ID_PTR]](i8 %0)
|
||||
|
||||
// CHECK-WINDOWSX64: i8 [[CHAR_ID_BRIDGE]](i8 %0)
|
||||
// CHECK-WINDOWSX64: [[CHAR_ID_PTR:%[0-9]+]] = load i8 (i8)*, i8 (i8)** @{{.*char_id}}
|
||||
// CHECK-WINDOWSX64: call i8 [[CHAR_ID_PTR]](i8 %0)
|
||||
|
||||
|
||||
// CHECK-DEFAULTABI: zeroext i8 [[UNSIGNED_CHAR_ID_BRIDGE]](i8 zeroext %0)
|
||||
// CHECK-DEFAULTABI: [[UNSIGNED_CHAR_ID_PTR:%[0-9]+]] = load i8 (i8)*, i8 (i8)** @{{.*unsigned_char_id}}
|
||||
// CHECK-DEFAULTABI: call zeroext i8 [[UNSIGNED_CHAR_ID_PTR]](i8 zeroext %0)
|
||||
|
||||
// CHECK-AAPCS: i8 [[UNSIGNED_CHAR_ID_BRIDGE]](i8 %0)
|
||||
// CHECK-AAPCS: [[UNSIGNED_CHAR_ID_PTR:%[0-9]+]] = load i8 (i8)*, i8 (i8)** @{{.*unsigned_char_id}}
|
||||
// CHECK-AAPCS: call i8 [[UNSIGNED_CHAR_ID_PTR]](i8 %0)
|
||||
|
||||
// CHECK-WINDOWSX64: i8 [[UNSIGNED_CHAR_ID_BRIDGE]](i8 %0)
|
||||
// CHECK-WINDOWSX64: [[UNSIGNED_CHAR_ID_PTR:%[0-9]+]] = load i8 (i8)*, i8 (i8)** @{{.*unsigned_char_id}}
|
||||
// CHECK-WINDOWSX64: call i8 [[UNSIGNED_CHAR_ID_PTR]](i8 %0)
|
||||
|
||||
|
||||
// CHECK-DEFAULTABI: signext i16 [[SHORT_ID_BRIDGE]](i16 signext %0)
|
||||
// CHECK-DEFAULTABI: [[SHORT_ID_PTR:%[0-9]+]] = load i16 (i16)*, i16 (i16)** @{{.*short_id}}
|
||||
// CHECK-DEFAULTABI: call signext i16 [[SHORT_ID_PTR]](i16 signext %0)
|
||||
|
||||
// CHECK-AAPCS: i16 [[SHORT_ID_BRIDGE]](i16 %0)
|
||||
// CHECK-AAPCS: [[SHORT_ID_PTR:%[0-9]+]] = load i16 (i16)*, i16 (i16)** @{{.*short_id}}
|
||||
// CHECK-AAPCS: call i16 [[SHORT_ID_PTR]](i16 %0)
|
||||
|
||||
// CHECK-WINDOWSX64: i16 [[SHORT_ID_BRIDGE]](i16 %0)
|
||||
// CHECK-WINDOWSX64: [[SHORT_ID_PTR:%[0-9]+]] = load i16 (i16)*, i16 (i16)** @{{.*short_id}}
|
||||
// CHECK-WINDOWSX64: call i16 [[SHORT_ID_PTR]](i16 %0)
|
||||
|
||||
|
||||
// CHECK-DEFAULTABI: zeroext i16 [[UNSIGNED_SHORT_ID_BRIDGE]](i16 zeroext %0)
|
||||
// CHECK-DEFAULTABI: [[UNSIGNED_SHORT_ID_PTR:%[0-9]+]] = load i16 (i16)*, i16 (i16)** @{{.*unsigned_short_id}}
|
||||
// CHECK-DEFAULTABI: call zeroext i16 [[UNSIGNED_SHORT_ID_PTR]](i16 zeroext %0)
|
||||
|
||||
// CHECK-AAPCS: i16 [[UNSIGNED_SHORT_ID_BRIDGE]](i16 %0)
|
||||
// CHECK-AAPCS: [[UNSIGNED_SHORT_ID_PTR:%[0-9]+]] = load i16 (i16)*, i16 (i16)** @{{.*unsigned_short_id}}
|
||||
// CHECK-AAPCS: call i16 [[UNSIGNED_SHORT_ID_PTR]](i16 %0)
|
||||
|
||||
// CHECK-WINDOWSX64: i16 [[UNSIGNED_SHORT_ID_BRIDGE]](i16 %0)
|
||||
// CHECK-WINDOWSX64: [[UNSIGNED_SHORT_ID_PTR:%[0-9]+]] = load i16 (i16)*, i16 (i16)** @{{.*unsigned_short_id}}
|
||||
// CHECK-WINDOWSX64: call i16 [[UNSIGNED_SHORT_ID_PTR]](i16 %0)
|
||||
|
||||
|
||||
// CHECK-DEFAULTABI: i32 [[STATIC_C_FUNCTION_BRIDGE]](i32 %0, i16 signext %1)
|
||||
// CHECK-DEFAULTABI: call i32 {{@_.*_knbridge[0-9]+}}(i32 %0, i16 signext %1)
|
||||
|
||||
// CHECK-AAPCS: i32 [[STATIC_C_FUNCTION_BRIDGE]](i32 %0, i16 %1)
|
||||
// CHECK-AAPCS: call i32 {{@_.*_knbridge[0-9]+}}(i32 %0, i16 %1)
|
||||
|
||||
// CHECK-WINDOWSX64: i32 [[STATIC_C_FUNCTION_BRIDGE]](i32 %0, i16 %1)
|
||||
// CHECK-WINDOWSX64: call i32 {{@_.*_knbridge[0-9]+}}(i32 %0, i16 %1)
|
||||
|
||||
|
||||
// CHECK-DEFAULTABI: i32 [[CALLBACK_USER_BRIDGE]](i8* %0)
|
||||
// CHECK-DEFAULTABI: [[CALLBACK_USER_PTR:%[0-9]+]] = load i32 (i8*)*, i32 (i8*)** @{{.*callbackUser}}
|
||||
// CHECK-DEFAULTABI: call i32 [[CALLBACK_USER_PTR]](i8* %0)
|
||||
|
||||
// CHECK-AAPCS: i32 [[CALLBACK_USER_BRIDGE]](i8* %0)
|
||||
// CHECK-AAPCS: [[CALLBACK_USER_PTR:%[0-9]+]] = load i32 (i8*)*, i32 (i8*)** @{{.*callbackUser}}
|
||||
// CHECK-AAPCS: call i32 [[CALLBACK_USER_PTR]](i8* %0)
|
||||
|
||||
// CHECK-WINDOWSX64: i32 [[CALLBACK_USER_BRIDGE]](i8* %0)
|
||||
// CHECK-WINDOWSX64: [[CALLBACK_USER_PTR:%[0-9]+]] = load i32 (i8*)*, i32 (i8*)** @{{.*callbackUser}}
|
||||
// CHECK-WINDOWSX64: call i32 [[CALLBACK_USER_PTR]](i8* %0)
|
||||
@@ -0,0 +1,26 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// FILECHECK_STAGE: CStubs
|
||||
|
||||
import kotlin.reflect.*
|
||||
|
||||
// CHECK: [[REG_FOR_1024:@[0-9]+]] = internal unnamed_addr constant { %struct.ObjHeader, i32 } { %struct.ObjHeader { %struct.TypeInfo* {{.*}} }, i32 1024 }
|
||||
// CHECK-NOT: internal unnamed_addr constant { %struct.ObjHeader, i32 } { %struct.ObjHeader { %struct.TypeInfo* {{.*}} }, i32 1024 }
|
||||
|
||||
// CHECK: internal unnamed_addr constant { %struct.ArrayHeader, [3 x %struct.ObjHeader*] } { %struct.ArrayHeader { %struct.TypeInfo* {{.*}}, i32 3 }, [3 x %struct.ObjHeader*] [%struct.ObjHeader* getelementptr inbounds ({ %struct.ObjHeader, i32 }, { %struct.ObjHeader, i32 }* [[REG_FOR_1024]], i32 0, i32 0), %struct.ObjHeader* getelementptr inbounds ({ %struct.ObjHeader, i32 }, { %struct.ObjHeader, i32 }* [[REG_FOR_2048:@[0-9]+]], i32 0, i32 0), %struct.ObjHeader* getelementptr inbounds ({ %struct.ObjHeader, i32 }, { %struct.ObjHeader, i32 }* [[REG_FOR_4096:@[0-9]+]], i32 0, i32 0)] }
|
||||
// CHECK-NOT: internal unnamed_addr constant { %struct.ArrayHeader, [3 x %struct.ObjHeader*] } { %struct.ArrayHeader { %struct.TypeInfo* {{.*}}, i32 3 }, [3 x %struct.ObjHeader*] [%struct.ObjHeader* getelementptr inbounds ({ %struct.ObjHeader, i32 }, { %struct.ObjHeader, i32 }* [[REG_FOR_1024]], i32 0, i32 0), %struct.ObjHeader* getelementptr inbounds ({ %struct.ObjHeader, i32 }, { %struct.ObjHeader, i32 }* [[REG_FOR_2048]], i32 0, i32 0), %struct.ObjHeader* getelementptr inbounds ({ %struct.ObjHeader, i32 }, { %struct.ObjHeader, i32 }* [[REG_FOR_4096]], i32 0, i32 0)] }
|
||||
|
||||
// CHECK: internal unnamed_addr constant { %struct.ObjHeader, %struct.ObjHeader*, %struct.ObjHeader*, i1 } { %struct.ObjHeader { %struct.TypeInfo* {{.*}} }, %struct.ObjHeader* getelementptr inbounds ({ %struct.ObjHeader, i8* }, { %struct.ObjHeader, i8* }* [[REG_FOR_CLASSIFIER_FIELD:@[0-9]+]], i32 0, i32 0), %struct.ObjHeader* getelementptr inbounds ({ %struct.ObjHeader, %struct.ObjHeader*, %struct.ObjHeader* }, { %struct.ObjHeader, %struct.ObjHeader*, %struct.ObjHeader* }* [[REG_FOR_ARGUMENTS_FIELD:@[0-9]+]], i32 0, i32 0), i1 false }
|
||||
// CHECK-NOT: internal unnamed_addr constant { %struct.ObjHeader, %struct.ObjHeader*, %struct.ObjHeader*, i1 } { %struct.ObjHeader { %struct.TypeInfo* {{.*}} }, %struct.ObjHeader* getelementptr inbounds ({ %struct.ObjHeader, i8* }, { %struct.ObjHeader, i8* }* [[REG_FOR_CLASSIFIER_FIELD]], i32 0, i32 0), %struct.ObjHeader* getelementptr inbounds ({ %struct.ObjHeader, %struct.ObjHeader*, %struct.ObjHeader* }, { %struct.ObjHeader, %struct.ObjHeader*, %struct.ObjHeader* }* [[REG_FOR_ARGUMENTS_FIELD]], i32 0, i32 0), i1 false }
|
||||
|
||||
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:#box(){}kotlin.String"
|
||||
fun box(): String {
|
||||
println(1024)
|
||||
println(1024)
|
||||
|
||||
println(arrayOf(1024, 2048, 4096))
|
||||
println(arrayOf(1024, 2048, 4096))
|
||||
|
||||
println(typeOf<Map<String, String>>())
|
||||
println(typeOf<Map<String, String>>())
|
||||
return "OK"
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// FILECHECK_STAGE: CStubs
|
||||
|
||||
value class A(val i: Int)
|
||||
value class B(val a: A)
|
||||
value class C(val s: String)
|
||||
|
||||
fun defaultInt(a: Int = 1, aa: Int = 1) = a
|
||||
fun defaultA(a: A = A(1), aa: A = A(1)) = a.i
|
||||
fun defaultB(b: B = B(A(1)), bb: B = B(A(1))) = b.a.i
|
||||
fun defaultC(c: C = C("1"), cc: C = C("1")) = c.s
|
||||
|
||||
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:#box(){}kotlin.String"
|
||||
fun box(): String {
|
||||
// CHECK-LABEL: entry
|
||||
// CHECK-NOT: <Int-box>
|
||||
// CHECK-NOT: <A-box>
|
||||
// CHECK-NOT: <B-box>
|
||||
// CHECK-NOT: <C-box>
|
||||
|
||||
defaultInt()
|
||||
defaultA()
|
||||
defaultB()
|
||||
defaultC()
|
||||
defaultInt(1)
|
||||
defaultA(A(1))
|
||||
defaultB(B(A(1)))
|
||||
defaultC(C("1"))
|
||||
defaultInt(1, 1)
|
||||
defaultA(A(1), A(1))
|
||||
defaultB(B(A(1)), B(A(1)))
|
||||
defaultC(C("1"), C("1"))
|
||||
// CHECK-LABEL: epilogue:
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// FILECHECK_STAGE: CStubs
|
||||
|
||||
enum class COLOR {
|
||||
RED,
|
||||
GREEN,
|
||||
BLUE
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:#box(){}kotlin.String"
|
||||
fun box(): String {
|
||||
for (i in COLOR.values()) {
|
||||
// CHECK-DEBUG: = call i32 @"kfun:kotlin.Enum#<get-ordinal>(){}kotlin.Int"(
|
||||
// We inline .ordinal property access in case of opt build, so check direct field load instead.
|
||||
// CHECK-OPT: getelementptr inbounds %"kclassbody:kotlin.Enum#internal", %"kclassbody:kotlin.Enum#internal"* %{{[0-9a-z]*}}, i32 0, i32 2
|
||||
print(when (i) {
|
||||
// we can't check the register is same, because it can be saved on stack and loaded back
|
||||
// CHECK: icmp eq i32 %{{[0-9a-z]*}}, 0
|
||||
COLOR.RED -> 0xff0000
|
||||
// CHECK: icmp eq i32 %{{[0-9a-z]*}}, 1
|
||||
COLOR.GREEN -> 0x00ff00
|
||||
// CHECK: icmp eq i32 %{{[0-9a-z]*}}, 2
|
||||
COLOR.BLUE -> 0x0000ff
|
||||
})
|
||||
}
|
||||
// CHECK-LABEL: epilogue:
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// FILECHECK_STAGE: CStubs
|
||||
|
||||
class A(val x: Int)
|
||||
|
||||
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:#box(){}kotlin.String"
|
||||
fun box(): String {
|
||||
// CHECK-DEBUG: call %struct.ObjHeader* @AllocInstance
|
||||
// CHECK-OPT: alloca %"kclassbody:A#internal"
|
||||
val a = A(5)
|
||||
println(a.x)
|
||||
// CHECK-LABEL: epilogue:
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// IGNORE_BACKEND: NATIVE
|
||||
// FILECHECK_STAGE: CStubs
|
||||
|
||||
// The check below is intentionally wrong and must fail.
|
||||
// Test system should report test as passed due to IGNORE_BACKEND directive above.
|
||||
// CHECK-LABEL: NONEXISTENT
|
||||
fun box(): String = "OK"
|
||||
@@ -0,0 +1,19 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
|
||||
// Perform check after optimization pipeline because
|
||||
// LLVM might infer attributes.
|
||||
// FILECHECK_STAGE: LTOBitcodeOptimization
|
||||
|
||||
// NB: This is not a good test.
|
||||
// What we actually want to check is that Kotlin/Native compiler is able to produce "big"
|
||||
// binaries for 32-bit Apple Watch target. The problem is that such test is very-very-very
|
||||
// slow to compile (~20 min on a local machine) which is not acceptable for CI.
|
||||
//
|
||||
// Instead, here we check that none of the module's functions are compiled in the Thumb mode.
|
||||
// BL instructions in thumb mode have smaller ranges which causes "relocation out of range" failure.
|
||||
|
||||
// CHECK-WATCHOS_ARM32: target triple = "armv7k-apple-watchos2{{.+}}"
|
||||
|
||||
fun box() = "OK"
|
||||
|
||||
// CHECK-NOT: attributes #{{[0-9]+}} = { {{.+}}+thumb-mode{{.+}} }
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// FILECHECK_STAGE: CStubs
|
||||
|
||||
// CHECK: declare void @ThrowException(%struct.ObjHeader*) #[[THROW_EXCEPTION_DECLARATION_ATTRIBUTES:[0-9]+]]
|
||||
|
||||
// CHECK: void @"kfun:#flameThrower(){}kotlin.Nothing"() #[[FLAME_THROWER_DECLARATION_ATTRIBUTES:[0-9]+]]
|
||||
fun flameThrower(): Nothing {
|
||||
// CHECK: call void @ThrowException(%struct.ObjHeader* {{.*}}) #[[THROW_EXCEPTION_CALLSITE_ATTRIBUTES:[0-9]+]]
|
||||
throw Throwable("🔥")
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:#box(){}kotlin.String"
|
||||
fun box(): String {
|
||||
|
||||
// CHECK: invoke void @"kfun:#flameThrower(){}kotlin.Nothing"() #[[FLAME_THROWER_CALLSITE_ATTRIBUTES:[0-9]+]]
|
||||
try {
|
||||
flameThrower()
|
||||
} catch (e: Throwable) {
|
||||
return "OK"
|
||||
}
|
||||
return "FAIL: Uncaught exception"
|
||||
}
|
||||
|
||||
// CHECK-DAG: attributes #[[THROW_EXCEPTION_DECLARATION_ATTRIBUTES]] = {{{.*}}noreturn{{.*}}}
|
||||
// CHECK-DAG: attributes #[[THROW_EXCEPTION_CALLSITE_ATTRIBUTES]] = {{{.*}}noreturn{{.*}}}
|
||||
// CHECK-DAG: attributes #[[FLAME_THROWER_DECLARATION_ATTRIBUTES]] = {{{.*}}noreturn{{.*}}}
|
||||
// CHECK-DAG: attributes #[[FLAME_THROWER_CALLSITE_ATTRIBUTES]] = {{{.*}}noreturn{{.*}}}
|
||||
+132
@@ -0,0 +1,132 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// FILECHECK_STAGE: CStubs
|
||||
|
||||
import kotlin.reflect.KFunction2
|
||||
|
||||
fun <StringifyTP> stringify(collection: StringifyTP, size: (StringifyTP) -> Int, get: StringifyTP.(Int) -> Any?): String {
|
||||
var res = "["
|
||||
for (i in 0 until size(collection)) {
|
||||
if (i > 0) res += ", "
|
||||
res += collection.get(i).toString()
|
||||
}
|
||||
res += "]"
|
||||
return res
|
||||
}
|
||||
|
||||
interface I
|
||||
|
||||
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:#stringifyArray(kotlin.Array<0:0>){0\C2\A7<I>}kotlin.String"
|
||||
// CHECK-SAME: (%struct.ObjHeader* {{%[0-9]+}}, %struct.ObjHeader** {{%[0-9]+}})
|
||||
fun <StringifyArrayTP : I> stringifyArray(array: Array<StringifyArrayTP>) =
|
||||
// CHECK: call %struct.ObjHeader* @"kfun:#stringify(0:0;kotlin.Function1<0:0,kotlin.Int>;kotlin.Function2<0:0,kotlin.Int,kotlin.Any?>){0\C2\A7<kotlin.Any?>}kotlin.String"
|
||||
stringify(
|
||||
array,
|
||||
{ it.size }, // $stringifyArray$lambda$0$FUNCTION_REFERENCE$0
|
||||
Array<*>::get // $get$FUNCTION_REFERENCE$1
|
||||
)
|
||||
|
||||
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:#stringifyIntArray(kotlin.Array<kotlin.Int>){}kotlin.String"
|
||||
// CHECK-SAME: (%struct.ObjHeader* {{%[0-9]+}}, %struct.ObjHeader** {{%[0-9]+}})
|
||||
fun stringifyIntArray(array: Array<Int>) =
|
||||
// CHECK: call %struct.ObjHeader* @"kfun:#stringify(0:0;kotlin.Function1<0:0,kotlin.Int>;kotlin.Function2<0:0,kotlin.Int,kotlin.Any?>){0\C2\A7<kotlin.Any?>}kotlin.String"
|
||||
stringify(
|
||||
array,
|
||||
{ it.size }, // $stringifyIntArray$lambda$1$FUNCTION_REFERENCE$2
|
||||
Array<Int>::get // $get$FUNCTION_REFERENCE$3
|
||||
)
|
||||
|
||||
class N(val v: Int) : I {
|
||||
override fun toString() = v.toString()
|
||||
}
|
||||
|
||||
@Suppress("UNUSED_PARAMETER")
|
||||
fun <BazTP0, BazTP1> foo(p1: BazTP0, p2: BazTP1) {}
|
||||
|
||||
fun <QuxTP> bar() {
|
||||
val ref: KFunction2<QuxTP, QuxTP, Unit> = ::foo // $foo$FUNCTION_REFERENCE$4
|
||||
println(ref)
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:#box(){}kotlin.String"
|
||||
fun box(): String {
|
||||
println(stringifyArray(arrayOf(N(2), N(14))))
|
||||
println(stringifyIntArray(arrayOf(1, 2, 3)))
|
||||
|
||||
bar<Int>()
|
||||
bar<String>()
|
||||
|
||||
val ref: KFunction2<Int, Int, Unit> = ::foo // $foo$FUNCTION_REFERENCE$5
|
||||
println(ref)
|
||||
return "OK"
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define internal i32 @"kfun:$stringifyArray$lambda$0$FUNCTION_REFERENCE$0.invoke#internal"
|
||||
// CHECK-SAME: (%struct.ObjHeader* {{%[0-9]+}}, %struct.ObjHeader* {{%[0-9]+}})
|
||||
|
||||
// CHECK-LABEL: define internal void @"kfun:$stringifyArray$lambda$0$FUNCTION_REFERENCE$0.<init>#internal"
|
||||
// CHECK-SAME: (%struct.ObjHeader* {{%[0-9]+}})
|
||||
|
||||
// CHECK-LABEL: define internal %struct.ObjHeader* @"kfun:$stringifyArray$lambda$0$FUNCTION_REFERENCE$0.$<bridge-BNNN>invoke(kotlin.Array<1:0>){}kotlin.Int#internal"
|
||||
// CHECK-SAME: (%struct.ObjHeader* [[this:%[0-9]+]], %struct.ObjHeader* [[array:%[0-9]+]], %struct.ObjHeader** {{%[0-9]+}})
|
||||
// CHECK-OPT: call i32 @"kfun:$stringifyArray$lambda$0$FUNCTION_REFERENCE$0.invoke#internal"(%struct.ObjHeader* [[this]], %struct.ObjHeader* [[array]])
|
||||
// CHECK-DEBUG: call i32 @"kfun:$stringifyArray$lambda$0$FUNCTION_REFERENCE$0.invoke#internal"(%struct.ObjHeader* {{%[0-9]+}}, %struct.ObjHeader* {{%[0-9]+}})
|
||||
|
||||
// CHECK-LABEL: define internal %struct.ObjHeader* @"kfun:$get$FUNCTION_REFERENCE$1.invoke#internal"
|
||||
// CHECK-SAME: (%struct.ObjHeader* [[this:%[0-9]+]], %struct.ObjHeader* [[array:%[0-9]+]], i32 [[index:%[0-9]+]], %struct.ObjHeader** [[ret:%[0-9]+]])
|
||||
// CHECK-OPT: call %struct.ObjHeader* @Kotlin_Array_get(%struct.ObjHeader* [[array]], i32 [[index]], %struct.ObjHeader** [[ret]])
|
||||
// CHECK-DEBUG: call %struct.ObjHeader* @Kotlin_Array_get(%struct.ObjHeader* {{%[0-9]+}}, i32 {{%[0-9]+}}, %struct.ObjHeader** {{%[0-9]+}})
|
||||
|
||||
// CHECK-LABEL: define internal void @"kfun:$get$FUNCTION_REFERENCE$1.<init>#internal"
|
||||
// CHECK-SAME: (%struct.ObjHeader* {{%[0-9]+}})
|
||||
|
||||
// CHECK-LABEL: define internal %struct.ObjHeader* @"kfun:$get$FUNCTION_REFERENCE$1.$<bridge-NNNNB>invoke(kotlin.Array<*>;kotlin.Int){}kotlin.Any?#internal"
|
||||
// CHECK-SAME: (%struct.ObjHeader* [[this:%[0-9]+]], %struct.ObjHeader* [[array:%[0-9]+]], %struct.ObjHeader* [[boxedIndex:%[0-9]+]], %struct.ObjHeader** [[ret:%[0-9]+]])
|
||||
// CHECK-OPT: call %struct.ObjHeader* @"kfun:$get$FUNCTION_REFERENCE$1.invoke#internal"(%struct.ObjHeader* [[this]], %struct.ObjHeader* [[array]], i32 {{%[0-9]+}}, %struct.ObjHeader** [[ret]])
|
||||
// CHECK-DEBUG: call %struct.ObjHeader* @"kfun:$get$FUNCTION_REFERENCE$1.invoke#internal"(%struct.ObjHeader* {{%[0-9]+}}, %struct.ObjHeader* {{%[0-9]+}}, i32 {{%[0-9]+}}, %struct.ObjHeader** {{%[0-9]+}})
|
||||
|
||||
// CHECK-LABEL: define internal i32 @"kfun:$stringifyIntArray$lambda$1$FUNCTION_REFERENCE$2.invoke#internal"
|
||||
// CHECK-SAME: (%struct.ObjHeader* {{%[0-9]+}}, %struct.ObjHeader* {{%[0-9]+}})
|
||||
|
||||
// CHECK-LABEL: define internal void @"kfun:$stringifyIntArray$lambda$1$FUNCTION_REFERENCE$2.<init>#internal"
|
||||
// CHECK-SAME: (%struct.ObjHeader* {{%[0-9]+}})
|
||||
|
||||
// CHECK-LABEL: define internal %struct.ObjHeader* @"kfun:$stringifyIntArray$lambda$1$FUNCTION_REFERENCE$2.$<bridge-BNNN>invoke(kotlin.Array<kotlin.Int>){}kotlin.Int#internal"
|
||||
// CHECK-SAME: (%struct.ObjHeader* [[this:%[0-9]+]], %struct.ObjHeader* [[array:%[0-9]+]], %struct.ObjHeader** {{%[0-9]+}})
|
||||
// CHECK-OPT: call i32 @"kfun:$stringifyIntArray$lambda$1$FUNCTION_REFERENCE$2.invoke#internal"(%struct.ObjHeader* [[this]], %struct.ObjHeader* [[array]])
|
||||
// CHECK-DEBUG: call i32 @"kfun:$stringifyIntArray$lambda$1$FUNCTION_REFERENCE$2.invoke#internal"(%struct.ObjHeader* {{%[0-9]+}}, %struct.ObjHeader* {{%[0-9]+}})
|
||||
|
||||
// CHECK-LABEL: define internal i32 @"kfun:$get$FUNCTION_REFERENCE$3.invoke#internal"
|
||||
// CHECK-SAME: (%struct.ObjHeader* {{%[0-9]+}}, %struct.ObjHeader* {{%[0-9]+}}, i32 {{%[0-9]+}})
|
||||
|
||||
// CHECK-LABEL: define internal void @"kfun:$get$FUNCTION_REFERENCE$3.<init>#internal"
|
||||
// CHECK-SAME: (%struct.ObjHeader* {{%[0-9]+}})
|
||||
|
||||
// CHECK-LABEL: define internal %struct.ObjHeader* @"kfun:$get$FUNCTION_REFERENCE$3.$<bridge-BNNNB>invoke(kotlin.Array<kotlin.Int>;kotlin.Int){}kotlin.Int#internal"
|
||||
// CHECK-SAME: (%struct.ObjHeader* [[this:%[0-9]+]], %struct.ObjHeader* [[array:%[0-9]+]], %struct.ObjHeader* {{%[0-9]+}}, %struct.ObjHeader** {{%[0-9]+}})
|
||||
// CHECK-OPT: call i32 @"kfun:$get$FUNCTION_REFERENCE$3.invoke#internal"(%struct.ObjHeader* [[this]], %struct.ObjHeader* [[array]], i32 {{%[0-9]+}})
|
||||
// CHECK-DEBUG: call i32 @"kfun:$get$FUNCTION_REFERENCE$3.invoke#internal"(%struct.ObjHeader* {{%[0-9]+}}, %struct.ObjHeader* {{%[0-9]+}}, i32 {{%[0-9]+}})
|
||||
|
||||
// CHECK-LABEL: define internal void @"kfun:$foo$FUNCTION_REFERENCE$4.invoke#internal"
|
||||
// CHECK-SAME: (%struct.ObjHeader* {{%[0-9]+}}, %struct.ObjHeader* [[p1:%[0-9]+]], %struct.ObjHeader* [[p2:%[0-9]+]])
|
||||
// CHECK-OPT: call void @"kfun:#foo(0:0;0:1){0\C2\A7<kotlin.Any?>;1\C2\A7<kotlin.Any?>}"(%struct.ObjHeader* [[p1]], %struct.ObjHeader* [[p2]])
|
||||
// CHECK-DEBUG: call void @"kfun:#foo(0:0;0:1){0\C2\A7<kotlin.Any?>;1\C2\A7<kotlin.Any?>}"(%struct.ObjHeader* {{%[0-9]+}}, %struct.ObjHeader* {{%[0-9]+}})
|
||||
|
||||
// CHECK-LABEL: define internal void @"kfun:$foo$FUNCTION_REFERENCE$4.<init>#internal"
|
||||
// CHECK-SAME: (%struct.ObjHeader* {{%[0-9]+}})
|
||||
|
||||
// CHECK-LABEL: define internal %struct.ObjHeader* @"kfun:$foo$FUNCTION_REFERENCE$4.$<bridge-UNNNN>invoke(1:0;1:0){}#internal"
|
||||
// CHECK-SAME: (%struct.ObjHeader* [[this:%[0-9]+]], %struct.ObjHeader* [[p1:%[0-9]+]], %struct.ObjHeader* [[p2:%[0-9]+]], %struct.ObjHeader** {{%[0-9]+}})
|
||||
// CHECK-OPT: call void @"kfun:$foo$FUNCTION_REFERENCE$4.invoke#internal"(%struct.ObjHeader* [[this]], %struct.ObjHeader* [[p1]], %struct.ObjHeader* [[p2]])
|
||||
// CHECK-DEBUG: call void @"kfun:$foo$FUNCTION_REFERENCE$4.invoke#internal"(%struct.ObjHeader* {{%[0-9]+}}, %struct.ObjHeader* {{%[0-9]+}}, %struct.ObjHeader* {{%[0-9]+}})
|
||||
|
||||
// CHECK-LABEL: define internal void @"kfun:$foo$FUNCTION_REFERENCE$5.invoke#internal"
|
||||
// CHECK-SAME: (%struct.ObjHeader* {{%[0-9]+}}, i32 {{%[0-9]+}}, i32 {{%[0-9]+}})
|
||||
// CHECK: call void @"kfun:#foo(0:0;0:1){0\C2\A7<kotlin.Any?>;1\C2\A7<kotlin.Any?>}"(%struct.ObjHeader* {{%[0-9]+}}, %struct.ObjHeader* {{%[0-9]+}})
|
||||
|
||||
// CHECK-LABEL: define internal void @"kfun:$foo$FUNCTION_REFERENCE$5.<init>#internal"
|
||||
// CHECK-SAME: (%struct.ObjHeader* {{%[0-9]+}})
|
||||
|
||||
// CHECK-LABEL: define internal %struct.ObjHeader* @"kfun:$foo$FUNCTION_REFERENCE$5.$<bridge-UNNBB>invoke(kotlin.Int;kotlin.Int){}#internal"
|
||||
// CHECK-SAME: (%struct.ObjHeader* [[this:%[0-9]+]], %struct.ObjHeader* {{%[0-9]+}}, %struct.ObjHeader* {{%[0-9]+}}, %struct.ObjHeader** {{%[0-9]+}})
|
||||
// CHECK-OPT: call void @"kfun:$foo$FUNCTION_REFERENCE$5.invoke#internal"(%struct.ObjHeader* [[this]], i32 {{%[0-9]+}}, i32 {{%[0-9]+}})
|
||||
// CHECK-DEBUG: call void @"kfun:$foo$FUNCTION_REFERENCE$5.invoke#internal"(%struct.ObjHeader* {{%[0-9]+}}, i32 {{%[0-9]+}}, i32 {{%[0-9]+}})
|
||||
@@ -0,0 +1,26 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// FILECHECK_STAGE: CStubs
|
||||
|
||||
// CHECK-LABEL: "kfun:#and(kotlin.Int;kotlin.Int){}kotlin.Int"
|
||||
fun and(a: Int, b: Int): Int {
|
||||
// CHECK: and {{.*}}, {{.*}}
|
||||
return a and b
|
||||
// CHECK-LABEL: epilogue:
|
||||
}
|
||||
|
||||
// CHECK-LABEL: "kfun:#ieee754(kotlin.Float;kotlin.Float){}kotlin.Boolean"
|
||||
fun ieee754(a: Float, b: Float): Boolean {
|
||||
// CHECK: fcmp oeq float {{.*}}, {{.*}}
|
||||
return a == b
|
||||
// CHECK-LABEL: epilogue:
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:#box(){}kotlin.String"
|
||||
fun box(): String {
|
||||
val x = and(1, 2)
|
||||
val y = ieee754(0.0f, 1.0f)
|
||||
// CHECK-LABEL: epilogue:
|
||||
return if (x == 0 && !y)
|
||||
"OK"
|
||||
else "FAIL x=$x y=$y"
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// FILECHECK_STAGE: CStubs
|
||||
|
||||
class C {
|
||||
fun foo(x: Int) = x
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:#box(){}kotlin.String"
|
||||
// CHECK-OPT-NOT: Int-box
|
||||
// CHECK-DEBUG: Int-box
|
||||
// CHECK-NOT: Int-unbox
|
||||
// CHECK-LABEL: epilogue:
|
||||
fun box(): String {
|
||||
val c = C()
|
||||
val fooref = c::foo
|
||||
val result = fooref(42)
|
||||
return if( result == 42)
|
||||
"OK"
|
||||
else
|
||||
"FAIL: $result"
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// FILECHECK_STAGE: CStubs
|
||||
|
||||
class C<T> {
|
||||
fun foo(x: T) = x
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:#box(){}kotlin.String"
|
||||
// CHECK-NOT: Int-box
|
||||
// CHECK-OPT-NOT: Int-unbox
|
||||
// CHECK-DEBUG: Int-unbox
|
||||
// CHECK-LABEL: epilogue:
|
||||
fun box(): String {
|
||||
val c = C<Int>()
|
||||
val fooref = c::foo
|
||||
return if (fooref(42) == 42)
|
||||
"OK"
|
||||
else
|
||||
"FAIL"
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// FILECHECK_STAGE: CStubs
|
||||
|
||||
fun <T> T.foo() { println(this) }
|
||||
|
||||
// CHECK-LABEL: define void @"kfun:#bar(0:0){0\C2\A7<kotlin.Any?>}"
|
||||
// CHECK-SAME: (%struct.ObjHeader* [[x:%[0-9]+]])
|
||||
fun <BarTP> bar(x: BarTP) {
|
||||
// CHECK-OPT: call void @"kfun:$foo$FUNCTION_REFERENCE$0.<init>#internal"(%struct.ObjHeader* {{%[0-9]+}}, %struct.ObjHeader* [[x]])
|
||||
// CHECK-DEBUG: call void @"kfun:$foo$FUNCTION_REFERENCE$0.<init>#internal"(%struct.ObjHeader* {{%[0-9]+}}, %struct.ObjHeader* {{%[0-9]+}})
|
||||
println(x::foo)
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:#box(){}kotlin.String"
|
||||
fun box(): String {
|
||||
// CHECK: call void @"kfun:$foo$FUNCTION_REFERENCE$1.<init>#internal"(%struct.ObjHeader* {{%[0-9]+}}, i32 5)
|
||||
println(5::foo)
|
||||
|
||||
bar("hello")
|
||||
bar(42)
|
||||
return "OK"
|
||||
// CHECK-LABEL: epilogue:
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define internal void @"kfun:$foo$FUNCTION_REFERENCE$0.<init>#internal"
|
||||
// CHECK-SAME: (%struct.ObjHeader* {{%[0-9]+}}, %struct.ObjHeader* {{%[0-9]+}})
|
||||
|
||||
// CHECK-LABEL: define internal void @"kfun:$foo$FUNCTION_REFERENCE$1.<init>#internal"
|
||||
// CHECK-SAME: (%struct.ObjHeader* {{%[0-9]+}}, i32 {{%[0-9]+}})
|
||||
@@ -0,0 +1,23 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// FILECHECK_STAGE: CStubs
|
||||
|
||||
fun interface Foo {
|
||||
fun bar(x: Int): Any
|
||||
}
|
||||
|
||||
fun baz(x: Any): Int = x.hashCode()
|
||||
|
||||
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:#box(){}kotlin.String"
|
||||
// Boxing needs to be used now due to non-devirtualized call
|
||||
// CHECK-OPT: Int-box
|
||||
|
||||
// CHECK-NOT: Int-box
|
||||
// CHECK-NOT: Int-unbox
|
||||
// CHECK-LABEL: epilogue:
|
||||
|
||||
fun box(): String {
|
||||
val foo: Foo = Foo(::baz)
|
||||
return if (foo.bar(42) == 42)
|
||||
"OK"
|
||||
else "FAIL"
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// FILECHECK_STAGE: CStubs
|
||||
|
||||
fun interface Foo<T> {
|
||||
fun bar(x: T): Any
|
||||
}
|
||||
|
||||
fun baz(x: Any): Int = x.hashCode()
|
||||
|
||||
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:#box(){}kotlin.String"
|
||||
// CHECK-NOT: Int-box
|
||||
// CHECK-NOT: Int-unbox
|
||||
// CHECK-LABEL: epilogue:
|
||||
fun box(): String {
|
||||
val foo: Foo<Int> = Foo(::baz)
|
||||
return if (foo.bar(42) == 42)
|
||||
"OK"
|
||||
else "FAIL"
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// FILECHECK_STAGE: CStubs
|
||||
|
||||
fun interface Foo {
|
||||
fun bar(x: Int): Int
|
||||
}
|
||||
|
||||
fun baz(x: Int): Int = x.hashCode()
|
||||
|
||||
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:#box(){}kotlin.String"
|
||||
// CHECK-OPT-NOT: Int-box
|
||||
// CHECK-DEBUG: Int-box
|
||||
// CHECK-NOT: Int-unbox
|
||||
// CHECK-LABEL: epilogue:
|
||||
fun box(): String {
|
||||
val foo: Foo = Foo(::baz)
|
||||
val result = foo.bar(42)
|
||||
return if( result == 42 )
|
||||
"OK"
|
||||
else "FAIL: $result"
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// FILECHECK_STAGE: CStubs
|
||||
|
||||
fun interface Foo<T> {
|
||||
fun bar(x: T): Int
|
||||
}
|
||||
|
||||
fun baz(x: Any): Int = x.hashCode()
|
||||
|
||||
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:#box(){}kotlin.String"
|
||||
// CHECK-OPT-NOT: Int-box
|
||||
// CHECK-DEBUG: Int-box
|
||||
// CHECK-NOT: Int-unbox
|
||||
// CHECK-LABEL: epilogue:
|
||||
fun box(): String {
|
||||
val foo: Foo<Int> = Foo(::baz)
|
||||
val result = foo.bar(42)
|
||||
return if( result == 42 )
|
||||
"OK"
|
||||
else "FAIL: $result"
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// FILECHECK_STAGE: CStubs
|
||||
|
||||
fun plus1(x: Int) = x + 1
|
||||
|
||||
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:#box(){}kotlin.String"
|
||||
// CHECK-OPT-NOT: Int-box
|
||||
// CHECK-OPT-NOT: Int-unbox
|
||||
// CHECK-DEBUG: Int-box
|
||||
// CHECK-DEBUG: Int-unbox
|
||||
// CHECK-LABEL: epilogue:
|
||||
fun box(): String {
|
||||
|
||||
val ref = ::plus1
|
||||
var y = 0
|
||||
repeat(100000) {
|
||||
y += ref(it) // Should be devirtualized and invoked without boxing/unboxing (`Int-box`/`Int-unbox`)
|
||||
}
|
||||
if (y != 705082704)
|
||||
return "FAIL $y != 705082704"
|
||||
return "OK"
|
||||
}
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// FILECHECK_STAGE: CStubs
|
||||
|
||||
import kotlin.native.concurrent.*
|
||||
import kotlinx.cinterop.*
|
||||
|
||||
val arr: Array<String> = arrayOf("1")
|
||||
|
||||
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:#box(){}kotlin.String"
|
||||
@kotlinx.cinterop.ExperimentalForeignApi
|
||||
fun box(): String {
|
||||
println(arr.size.toByte() == arr[0].toByte())
|
||||
println(arr.size.toUByte() == arr[0].toUByte())
|
||||
println(arr.size.toShort() == arr[0].toShort())
|
||||
println(arr.size.toUShort() == arr[0].toUShort())
|
||||
println(arr.size.toInt() == arr[0].toInt())
|
||||
println(arr.size.toUInt() == arr[0].toUInt())
|
||||
println(arr.size.toLong() == arr[0].toLong())
|
||||
println(arr.size.toULong() == arr[0].toULong())
|
||||
println(arr.size.toFloat() == arr[0].toFloat())
|
||||
println(arr.size.toDouble() == arr[0].toDouble())
|
||||
println(Char(arr.size) == arr[0][0])
|
||||
println((arr.size == 1) == (arr[0] == "1")) // Boolean
|
||||
|
||||
memScoped {
|
||||
val var1: IntVar = alloc()
|
||||
val var2: IntVar = alloc()
|
||||
println(var1.ptr.rawValue == var2.ptr.rawValue)
|
||||
}
|
||||
|
||||
println(Result.success(arr.size) == Result.success(arr[0].toInt()))
|
||||
println(vectorOf(arr.size, arr.size, arr.size, arr.size) == vectorOf(arr[0].toInt(), arr[0].toInt(), arr[0].toInt(), arr[0].toInt()))
|
||||
|
||||
val w1 = Worker.start()
|
||||
val w2 = Worker.start()
|
||||
println(w1 == w2)
|
||||
|
||||
val f1 = w1.requestTermination()
|
||||
val f2 = w2.requestTermination()
|
||||
println(f1 == f2)
|
||||
|
||||
f1.result
|
||||
f2.result
|
||||
|
||||
return "OK"
|
||||
}
|
||||
// CHECK-OPT-NOT: {{call|invoke}} i64 @"kfun:kotlin#<Long-unbox>
|
||||
// CHECK-OPT-NOT: {{call|invoke}} i64 @"kfun:kotlin#<ULong-unbox>
|
||||
|
||||
// CHECK-OPT-NOT: {{call|invoke}} i32 @"kfun:kotlin#<Int-unbox>
|
||||
// CHECK-OPT-NOT: {{call|invoke}} i32 @"kfun:kotlin#<UInt-unbox>
|
||||
|
||||
// CHECK-OPT-NOT: {{call|invoke}} {{signext i16|i16}} @"kfun:kotlin#<Short-unbox>
|
||||
// CHECK-OPT-NOT: {{call|invoke}} {{zeroext i16|i16}} @"kfun:kotlin#<UShort-unbox>
|
||||
|
||||
// CHECK-OPT-NOT: {{call|invoke}} {{signext i8|i8}} @"kfun:kotlin#<Byte-unbox>
|
||||
// CHECK-OPT-NOT: {{call|invoke}} {{zeroext i8|i8}} @"kfun:kotlin#<UByte-unbox>
|
||||
|
||||
// CHECK-OPT-NOT: {{call|invoke}} {{zeroext i16|i16}} @"kfun:kotlin#<Char-unbox>
|
||||
// CHECK-OPT-NOT: {{call|invoke}} {{zeroext i1|i1}} @"kfun:kotlin#<Boolean-unbox>
|
||||
|
||||
// CHECK-OPT-NOT: {{call|invoke}} double @"kfun:kotlin#<Double-unbox>
|
||||
// CHECK-OPT-NOT: {{call|invoke}} float @"kfun:kotlin#<Float-unbox>
|
||||
|
||||
// CHECK-OPT-NOT: {{call|invoke}} i8* @"kfun:kotlin.native.internal#<NativePtr-unbox>
|
||||
// CHECK-OPT-NOT: {{call|invoke}} i32 @"kfun:kotlin.native.concurrent#<Future-unbox>
|
||||
// CHECK-OPT-NOT: {{call|invoke}} i32 @"kfun:kotlin.native.concurrent#<Worker-unbox>
|
||||
// CHECK-OPT-NOT: {{call|invoke}} <4 x float> @"kfun:kotlin.native#<Vector128-unbox>
|
||||
// CHECK-OPT-NOT: {{call|invoke}} %struct.ObjHeader* @"kfun:kotlin#<Result-unbox>
|
||||
|
||||
// CHECK-LABEL: epilogue:
|
||||
// On APPLE targets, generated functions <T>ToNSNumber may contain non-converted invocations of unbox functions.
|
||||
// CHECK-APPLE: {{IntToNSNumber|LongToNSNumber|ByteToNSNumber|ShortToNSNumber|FloatToNSNumber|DoubleToNSNumber}}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// FILECHECK_STAGE: CStubs
|
||||
|
||||
import kotlinx.cinterop.*
|
||||
|
||||
// CHECK-AAPCS-OPT-LABEL: define i1 @"kfun:kotlinx.cinterop.CPointer#equals(kotlin.Any?){}kotlin.Boolean"(i8* %0, %struct.ObjHeader* %1)
|
||||
// CHECK-DEFAULTABI-OPT-LABEL: define zeroext i1 @"kfun:kotlinx.cinterop.CPointer#equals(kotlin.Any?){}kotlin.Boolean"(i8* %0, %struct.ObjHeader* %1)
|
||||
// CHECK-WINDOWSX64-OPT-LABEL: define zeroext i1 @"kfun:kotlinx.cinterop.CPointer#equals(kotlin.Any?){}kotlin.Boolean"(i8* %0, %struct.ObjHeader* %1)
|
||||
// CHECK-OPT: call i8* @"kfun:kotlinx.cinterop#<CPointer-unbox>(kotlin.Any?){}kotlinx.cinterop.CPointer<-1:0>?"
|
||||
|
||||
// This test is useless in debug mode.
|
||||
// TODO(KT-59288): add ability to ignore tests in debug mode
|
||||
// CHECK-DEBUG-LABEL: define %struct.ObjHeader* @"kfun:#box(){}kotlin.String"
|
||||
|
||||
@kotlinx.cinterop.ExperimentalForeignApi
|
||||
fun box(): String = memScoped {
|
||||
val var1: IntVar = alloc()
|
||||
val var2: IntVar = alloc()
|
||||
return if (var1.ptr == var2.ptr) "FAIL" else "OK"
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// FILECHECK_STAGE: CStubs
|
||||
|
||||
import kotlinx.cinterop.*
|
||||
|
||||
// CHECK-OPT-LABEL: define i8* @"kfun:kotlinx.cinterop#interpretOpaquePointed(kotlin.native.internal.NativePtr){}kotlinx.cinterop.NativePointed"(i8* %0)
|
||||
// CHECK-OPT: call i8* @"kfun:kotlinx.cinterop#<NativePointed-unbox>(kotlin.Any?){}kotlinx.cinterop.NativePointed?"
|
||||
|
||||
// This test is useless in debug mode.
|
||||
// TODO(KT-59288): add ability to ignore tests in debug mode
|
||||
// CHECK-DEBUG-LABEL: define %struct.ObjHeader* @"kfun:#box(){}kotlin.String"
|
||||
|
||||
@kotlinx.cinterop.ExperimentalForeignApi
|
||||
fun box(): String = memScoped {
|
||||
val var1: NativePointed = alloc(4, 4)
|
||||
return if (interpretOpaquePointed(var1.rawPtr) is NativePointed) "OK" else "FAIL"
|
||||
}
|
||||
Vendored
+22
@@ -0,0 +1,22 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// FILECHECK_STAGE: CStubs
|
||||
|
||||
import kotlinx.cinterop.*
|
||||
|
||||
// CHECK-AAPCS-OPT-LABEL: define i1 @"kfun:kotlin.native.internal.NonNullNativePtr#equals(kotlin.Any?){}kotlin.Boolean"(i8* %0, %struct.ObjHeader* %1)
|
||||
// CHECK-DEFAULTABI-OPT-LABEL: define zeroext i1 @"kfun:kotlin.native.internal.NonNullNativePtr#equals(kotlin.Any?){}kotlin.Boolean"(i8* %0, %struct.ObjHeader* %1)
|
||||
// CHECK-WINDOWSX64-OPT-LABEL: define zeroext i1 @"kfun:kotlin.native.internal.NonNullNativePtr#equals(kotlin.Any?){}kotlin.Boolean"(i8* %0, %struct.ObjHeader* %1)
|
||||
// CHECK-OPT: call i8* @"kfun:kotlin.native.internal#<NonNullNativePtr-unbox>(kotlin.Any?){}kotlin.native.internal.NonNullNativePtr?"
|
||||
|
||||
// This test is useless in debug mode.
|
||||
// TODO(KT-59288): add ability to ignore tests in debug mode
|
||||
// CHECK-DEBUG-LABEL: define %struct.ObjHeader* @"kfun:#box(){}kotlin.String"
|
||||
|
||||
@kotlinx.cinterop.ExperimentalForeignApi
|
||||
fun box(): String = memScoped {
|
||||
val var1: IntVar = alloc()
|
||||
val var2: IntVar = alloc()
|
||||
// The first one is K1, the second one is K2.
|
||||
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
|
||||
return if (var1.ptr.value as Any == var2.ptr.value as Any) "FAIL" else "OK"
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// FILECHECK_STAGE: CStubs
|
||||
|
||||
import kotlinx.cinterop.*
|
||||
|
||||
// CHECK-AAPCS-OPT-LABEL: define i1 @"kfun:kotlinx.cinterop.StableRef#equals(kotlin.Any?){}kotlin.Boolean"(i8* %0, %struct.ObjHeader* %1)
|
||||
// CHECK-DEFAULTABI-OPT-LABEL: define zeroext i1 @"kfun:kotlinx.cinterop.StableRef#equals(kotlin.Any?){}kotlin.Boolean"(i8* %0, %struct.ObjHeader* %1)
|
||||
// CHECK-WINDOWSX64-OPT-LABEL: define zeroext i1 @"kfun:kotlinx.cinterop.StableRef#equals(kotlin.Any?){}kotlin.Boolean"(i8* %0, %struct.ObjHeader* %1)
|
||||
|
||||
// CHECK-OPT: call i8* @"kfun:kotlinx.cinterop#<StableRef-unbox>(kotlin.Any?){}kotlinx.cinterop.StableRef<-1:0>?"
|
||||
|
||||
// CHECK-OPT-LABEL: epilogue:
|
||||
|
||||
// This test is useless in debug mode.
|
||||
// TODO(KT-59288): add ability to ignore tests in debug mode
|
||||
// CHECK-DEBUG-LABEL: define %struct.ObjHeader* @"kfun:#box(){}kotlin.String"
|
||||
|
||||
@kotlinx.cinterop.ExperimentalForeignApi
|
||||
fun box(): String {
|
||||
val ref1 = StableRef.create(Any())
|
||||
val ref2 = StableRef.create(Any())
|
||||
val isEqual = ref1 == ref2
|
||||
ref2.dispose()
|
||||
ref1.dispose()
|
||||
return if (!isEqual) "OK" else "FAIL"
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// FILECHECK_STAGE: CStubs
|
||||
|
||||
// CHECK-AAPCS-OPT-LABEL: define i1 @"kfun:kotlin.UByteArray#equals(kotlin.Any?){}kotlin.Boolean"(%struct.ObjHeader* %0, %struct.ObjHeader* %1)
|
||||
// CHECK-DEFAULTABI-OPT-LABEL: define zeroext i1 @"kfun:kotlin.UByteArray#equals(kotlin.Any?){}kotlin.Boolean"(%struct.ObjHeader* %0, %struct.ObjHeader* %1)
|
||||
// CHECK-WINDOWSX64-OPT-LABEL: define zeroext i1 @"kfun:kotlin.UByteArray#equals(kotlin.Any?){}kotlin.Boolean"(%struct.ObjHeader* %0, %struct.ObjHeader* %1)
|
||||
|
||||
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:#box(){}kotlin.String"
|
||||
|
||||
// CHECK-OPT: call %struct.ObjHeader* @"kfun:kotlin#<UByteArray-unbox>(kotlin.Any?){}kotlin.UByteArray?"
|
||||
|
||||
// CHECK-LABEL: epilogue:
|
||||
|
||||
fun box(): String {
|
||||
val arr1 = UByteArray(10) { it.toUByte() }
|
||||
val arr2 = UByteArray(10) { (it / 2).toUByte() }
|
||||
return if (arr1 == arr2) "FAIL" else "OK"
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
// TARGET_BACKEND: NATIVE
|
||||
// FILECHECK_STAGE: CStubs
|
||||
|
||||
// CHECK-AAPCS-OPT-LABEL: define i1 @"kfun:kotlin.UIntArray#equals(kotlin.Any?){}kotlin.Boolean"(%struct.ObjHeader* %0, %struct.ObjHeader* %1)
|
||||
// CHECK-DEFAULTABI-OPT-LABEL: define zeroext i1 @"kfun:kotlin.UIntArray#equals(kotlin.Any?){}kotlin.Boolean"(%struct.ObjHeader* %0, %struct.ObjHeader* %1)
|
||||
// CHECK-WINDOWSX64-OPT-LABEL: define zeroext i1 @"kfun:kotlin.UIntArray#equals(kotlin.Any?){}kotlin.Boolean"(%struct.ObjHeader* %0, %struct.ObjHeader* %1)
|
||||
|
||||
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:#box(){}kotlin.String"
|
||||
|
||||
// CHECK-OPT: call %struct.ObjHeader* @"kfun:kotlin#<UIntArray-unbox>(kotlin.Any?){}kotlin.UIntArray?"
|
||||
|
||||
// CHECK-LABEL: epilogue:
|
||||
|
||||
fun box(): String {
|
||||
val arr1 = UIntArray(10) { it.toUInt() }
|
||||
val arr2 = UIntArray(10) { (it / 2).toUInt() }
|
||||
return if (arr1 == arr2) "FAIL" else "OK"
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user