[Wasm] Support main function

This commit is contained in:
Svyatoslav Kuzmich
2021-10-13 12:08:54 +03:00
parent af18b10da9
commit 0f66f85cf9
22 changed files with 259 additions and 122 deletions
@@ -323,9 +323,8 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
val runner = """
export default WebAssembly.instantiateStreaming(fetch('${outputWasmFile.name}'), { runtime, js_code }).then((it) => {
wasmInstance = it.instance;
wasmInstance.exports.__init?.();
wasmInstance.exports.startUnitTests?.();
wasmInstance.exports.main?.();
return it.instance.exports;
});
@@ -14,9 +14,7 @@ import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.impl.EmptyPackageFragmentDescriptor
import org.jetbrains.kotlin.ir.*
import org.jetbrains.kotlin.ir.backend.js.JsCommonBackendContext
import org.jetbrains.kotlin.ir.backend.js.JsCommonCoroutineSymbols
import org.jetbrains.kotlin.ir.backend.js.JsMapping
import org.jetbrains.kotlin.ir.backend.js.*
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
import org.jetbrains.kotlin.ir.backend.js.lower.JsInnerClassesSupport
import org.jetbrains.kotlin.ir.builders.declarations.addFunction
@@ -35,8 +33,8 @@ import org.jetbrains.kotlin.name.Name
class WasmBackendContext(
val module: ModuleDescriptor,
override val irBuiltIns: IrBuiltIns,
@Suppress("UNUSED_PARAMETER") symbolTable: SymbolTable,
@Suppress("UNUSED_PARAMETER") irModuleFragment: IrModuleFragment,
symbolTable: SymbolTable,
irModuleFragment: IrModuleFragment,
val additionalExportedDeclarations: Set<FqName>,
override val configuration: CompilerConfiguration,
) : JsCommonBackendContext {
@@ -90,15 +88,17 @@ class WasmBackendContext(
}
}
val startFunction = irFactory.buildFun {
name = Name.identifier("startFunction")
fun createInitFunction(identifier: String): IrSimpleFunction = irFactory.buildFun {
name = Name.identifier(identifier)
returnType = irBuiltIns.unitType
}.apply {
body = irFactory.createBlockBody(UNDEFINED_OFFSET, UNDEFINED_OFFSET)
internalPackageFragment.addChild(this)
}
val fieldInitFunction = createInitFunction("fieldInit")
val mainCallsWrapperFunction = createInitFunction("mainCallsWrapper")
override val sharedVariablesManager =
WasmSharedVariablesManager(this, irBuiltIns, internalPackageFragment)
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.ir.backend.js.lower.coroutines.AddContinuationToNonL
import org.jetbrains.kotlin.ir.backend.js.lower.coroutines.JsSuspendFunctionsLowering
import org.jetbrains.kotlin.ir.backend.js.lower.inline.RemoveInlineDeclarationsWithReifiedTypeParametersLowering
import org.jetbrains.kotlin.ir.backend.js.lower.inline.WrapInlineDeclarationsWithReifiedTypeParametersLowering
import org.jetbrains.kotlin.ir.backend.wasm.lower.generateMainFunctionCalls
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
@@ -269,6 +270,12 @@ private val addContinuationToFunctionCallsLoweringPhase = makeWasmModulePhase(
)
)
private val addMainFunctionCallsLowering = makeCustomWasmModulePhase(
::generateMainFunctionCalls,
name = "GenerateMainFunctionCalls",
description = "Generate main function calls into start function",
)
private val defaultArgumentStubGeneratorPhase = makeWasmModulePhase(
::DefaultArgumentStubGenerator,
name = "DefaultArgumentStubGenerator",
@@ -521,6 +528,7 @@ val wasmPhases = NamedCompilerPhase(
addContinuationToNonLocalSuspendFunctionsLoweringPhase then
addContinuationToFunctionCallsLoweringPhase then
addMainFunctionCallsLowering then
tryCatchCanonicalization then
returnableBlockLoweringPhase then
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.ir.builders.declarations.addFunction
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.classifierOrFail
@@ -72,6 +73,10 @@ class WasmSymbols(
override val returnIfSuspended =
getInternalFunction("returnIfSuspended")
val coroutineEmptyContinuation: IrPropertySymbol = symbolTable.referenceProperty(
getProperty(FqName.fromSegments(listOf("kotlin", "wasm", "internal", "EmptyContinuation")))
)
override val functionAdapter: IrClassSymbol
get() = TODO()
@@ -9,7 +9,6 @@ import org.jetbrains.kotlin.backend.common.ir.isOverridableOrOverrides
import org.jetbrains.kotlin.backend.wasm.WasmBackendContext
import org.jetbrains.kotlin.backend.wasm.lower.wasmSignature
import org.jetbrains.kotlin.backend.wasm.utils.*
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.ir.IrBuiltIns
import org.jetbrains.kotlin.ir.IrElement
@@ -18,7 +17,6 @@ import org.jetbrains.kotlin.ir.backend.js.utils.findUnitGetInstanceFunction
import org.jetbrains.kotlin.ir.backend.js.utils.realOverrideTarget
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.IrBlockBody
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
@@ -158,8 +156,13 @@ class DeclarationGenerator(val context: WasmModuleCodegenContext) : IrElementVis
context.defineFunction(declaration.symbol, function)
if (declaration == backendContext.startFunction)
context.setStartFunction(function)
val initPriority = when (declaration) {
backendContext.fieldInitFunction -> "0"
backendContext.mainCallsWrapperFunction -> "1"
else -> null
}
if (initPriority != null)
context.registerInitFunction(function, initPriority)
if (declaration.isExported(backendContext)) {
context.addExport(
@@ -82,7 +82,8 @@ class WasmCompiledModuleFragment(val irBuiltIns: IrBuiltIns) {
val jsFuns = mutableListOf<JsCodeSnippet>()
var startFunction: WasmFunction? = null
class FunWithPriority(val function: WasmFunction, val priority: String)
val initFunctions = mutableListOf<FunWithPriority>()
val scratchMemAddr = WasmSymbol<Int>()
val scratchMemSizeInBytes = 65_536
@@ -253,6 +254,15 @@ class WasmCompiledModuleFragment(val irBuiltIns: IrBuiltIns) {
)
}
val masterInitFunctionType = WasmFunctionType("__init_t", emptyList(), emptyList())
val masterInitFunction = WasmFunction.Defined("__init", masterInitFunctionType)
with(WasmIrExpressionBuilder(masterInitFunction.instructions)) {
initFunctions.sortedBy { it.priority }.forEach {
buildCall(WasmSymbol(it.function))
}
}
exports += WasmExport.Function("__init", masterInitFunction)
interfaceMethodTables.defined.forEach { (function, table) ->
val size = interfaceTableElementsLists[function]!!.size.toUInt()
table.limits = WasmLimits(size, size)
@@ -271,16 +281,16 @@ class WasmCompiledModuleFragment(val irBuiltIns: IrBuiltIns) {
val sortedRttGlobals = runtimeTypes.elements.sortedBy { (it.type as WasmRtt).depth }
val module = WasmModule(
functionTypes = functionTypes.elements + tagFuncType,
functionTypes = functionTypes.elements + tagFuncType + masterInitFunctionType,
gcTypes = gcTypes.elements,
importsInOrder = importedFunctions,
importedFunctions = importedFunctions,
definedFunctions = functions.elements.filterIsInstance<WasmFunction.Defined>(),
definedFunctions = functions.elements.filterIsInstance<WasmFunction.Defined>() + masterInitFunction,
tables = listOf(table) + interfaceMethodTables.elements,
memories = listOf(memory),
globals = globals.elements + sortedRttGlobals,
exports = exports,
startFunction = startFunction!!,
startFunction = null, // Module is initialized via export call
elements = listOf(elements) + interfaceTableElements,
data = data,
tags = listOf(tag)
@@ -23,7 +23,7 @@ interface WasmModuleCodegenContext : WasmBaseCodegenContext {
fun defineInterfaceMethodTable(irFunction: IrFunctionSymbol, wasmTable: WasmTable)
fun addJsFun(importName: String, jsCode: String)
fun setStartFunction(wasmFunction: WasmFunction)
fun registerInitFunction(wasmFunction: WasmFunction, priority: String)
fun addExport(wasmExport: WasmExport<*>)
fun registerVirtualFunction(irFunction: IrSimpleFunctionSymbol)
@@ -81,8 +81,8 @@ class WasmModuleCodegenContextImpl(
wasmFragment.definedClassITableData.define(irClass, table)
}
override fun setStartFunction(wasmFunction: WasmFunction) {
wasmFragment.startFunction = wasmFunction
override fun registerInitFunction(wasmFunction: WasmFunction, priority: String) {
wasmFragment.initFunctions += WasmCompiledModuleFragment.FunWithPriority(wasmFunction, priority)
}
override fun addExport(wasmExport: WasmExport<*>) {
@@ -29,8 +29,8 @@ import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
*/
class FieldInitializersLowering(val context: WasmBackendContext) : FileLoweringPass {
override fun lower(irFile: IrFile) {
val builder = context.createIrBuilder(context.startFunction.symbol)
val startFunctionBody = context.startFunction.body as IrBlockBody
val builder = context.createIrBuilder(context.fieldInitFunction.symbol)
val startFunctionBody = context.fieldInitFunction.body as IrBlockBody
irFile.acceptChildrenVoid(object : IrElementVisitorVoid {
override fun visitElement(element: IrElement) {
@@ -0,0 +1,49 @@
/*
* 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.
*/
package org.jetbrains.kotlin.ir.backend.wasm.lower
import org.jetbrains.kotlin.backend.common.ir.createArrayOfExpression
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
import org.jetbrains.kotlin.backend.wasm.WasmBackendContext
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.backend.js.utils.JsMainFunctionDetector
import org.jetbrains.kotlin.ir.backend.js.utils.isLoweredSuspendFunction
import org.jetbrains.kotlin.ir.backend.js.utils.isStringArrayParameter
import org.jetbrains.kotlin.ir.builders.irCall
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.expressions.IrBlockBody
import org.jetbrains.kotlin.ir.expressions.IrExpression
/**
* Find single most appropriate main function and call with empty arguments from
* [WasmBackendContext.mainCallsWrapperFunction].
*/
fun generateMainFunctionCalls(
context: WasmBackendContext,
module: IrModuleFragment
) {
val mainFunction = JsMainFunctionDetector(context).getMainFunctionOrNull(module) ?: return
val generateArgv = mainFunction.valueParameters.firstOrNull()?.isStringArrayParameter() ?: false
val generateContinuation = mainFunction.isLoweredSuspendFunction(context)
with(context.createIrBuilder(context.mainCallsWrapperFunction.symbol)) {
val argv = if (generateArgv) {
context.createArrayOfExpression(UNDEFINED_OFFSET, UNDEFINED_OFFSET, context.irBuiltIns.stringType, emptyList())
} else {
null
}
val continuation =
if (generateContinuation) {
irCall(context.wasmSymbols.coroutineEmptyContinuation.owner.getter!!)
} else {
null
}
(context.mainCallsWrapperFunction.body as IrBlockBody).statements += irCall(mainFunction).also { call ->
listOfNotNull(argv, continuation).forEachIndexed { index: Int, arg: IrExpression -> call.putValueArgument(index, arg) }
}
}
}
@@ -17,7 +17,7 @@ import org.jetbrains.kotlin.js.test.ir.semantics.*
import org.jetbrains.kotlin.js.test.semantics.*
import org.jetbrains.kotlin.js.test.wasm.semantics.AbstractIrCodegenBoxWasmTest
import org.jetbrains.kotlin.js.test.wasm.semantics.AbstractIrCodegenWasmJsInteropWasmTest
import org.jetbrains.kotlin.js.test.wasm.semantics.AbstractKotlinTestBoxWasmTest
import org.jetbrains.kotlin.js.test.wasm.semantics.AbstractJsTranslatorWasmTest
import org.jetbrains.kotlin.test.TargetBackend
fun main(args: Array<String>) {
@@ -32,14 +32,15 @@ fun main(args: Array<String>) {
model("box/", pattern = "^([^_](.+))\\.kt$", targetBackend = TargetBackend.JS)
}
testClass<AbstractKotlinTestBoxWasmTest> {
model("box/kotlin.test/", pattern = "^([^_](.+))\\.kt$", targetBackend = TargetBackend.WASM)
}
testClass<AbstractIrBoxJsTest> {
model("box/", pattern = "^([^_](.+))\\.kt$", targetBackend = TargetBackend.JS_IR)
}
testClass<AbstractJsTranslatorWasmTest> {
model("box/main", pattern = "^([^_](.+))\\.kt$", targetBackend = TargetBackend.WASM)
model("box/kotlin.test/", pattern = "^([^_](.+))\\.kt$", targetBackend = TargetBackend.WASM)
}
testClass<AbstractIrBoxJsES6Test> {
model("box/", pattern = "^([^_](.+))\\.kt$", targetBackend = TargetBackend.JS_IR_ES6)
}
@@ -140,7 +140,7 @@ abstract class BasicBoxTest(
val actualMainCallParameters = if (CALL_MAIN_PATTERN.matcher(fileContent).find())
MainCallParameters.mainWithArguments(listOf("testArg"))
MainCallParameters.mainWithArguments(listOf())
else
mainCallParameters
@@ -189,9 +189,10 @@ abstract class BasicWasmBoxTest(
const wasmBinary = read(String.raw`${outputWasmFile.absoluteFile}`, 'binary');
const wasmModule = new WebAssembly.Module(wasmBinary);
wasmInstance = new WebAssembly.Instance(wasmModule, { runtime, js_code });
const ${sanitizeName(config.moduleId)} = wasmInstance.exports;
wasmInstance.exports.__init();
const ${sanitizeName(config.moduleId)} = wasmInstance.exports;
wasmInstance.exports.startUnitTests?.();
const actualResult = importStringFromWasm(wasmInstance.exports.$testFunction());
@@ -212,7 +213,9 @@ abstract class BasicWasmBoxTest(
const response = await fetch("index.wasm");
const wasmBinary = await response.arrayBuffer();
wasmInstance = (await WebAssembly.instantiate(wasmBinary, { runtime, js_code })).instance;
wasmInstance.exports.__init();
wasmInstance.exports.startUnitTests?.();
const actualResult = importStringFromWasm(wasmInstance.exports.box());
if (actualResult !== "OK")
throw `Wrong box result '${'$'}{actualResult}'; Expected "OK"`;
@@ -17,7 +17,7 @@ abstract class AbstractIrCodegenWasmJsInteropWasmTest : BasicWasmBoxTest(
"codegen/wasmJsInteropJs"
)
abstract class AbstractKotlinTestBoxWasmTest : BasicWasmBoxTest(
"js/js.translator/testData/box/kotlin.test",
"codegen/wasmBoxKotlinTest"
)
abstract class AbstractJsTranslatorWasmTest : BasicWasmBoxTest(
TEST_DATA_DIR_PATH + "box/",
"js.translator/wasmBox"
)
@@ -0,0 +1,133 @@
/*
* 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.
*/
package org.jetbrains.kotlin.js.test.wasm.semantics;
import com.intellij.testFramework.TestDataPath;
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
import org.jetbrains.kotlin.test.KotlinTestUtils;
import org.jetbrains.kotlin.test.util.KtTestUtil;
import org.jetbrains.kotlin.test.TargetBackend;
import org.jetbrains.kotlin.test.TestMetadata;
import org.junit.runner.RunWith;
import java.io.File;
import java.util.regex.Pattern;
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all")
@RunWith(JUnit3RunnerWithInners.class)
public class JsTranslatorWasmTestGenerated extends AbstractJsTranslatorWasmTest {
@TestMetadata("js/js.translator/testData/box/main")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Main extends AbstractJsTranslatorWasmTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest0(this::doTest, TargetBackend.WASM, testDataFilePath);
}
public void testAllFilesPresentInMain() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/main"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true);
}
@TestMetadata("differentMains.kt")
public void testDifferentMains() throws Exception {
runTest("js/js.translator/testData/box/main/differentMains.kt");
}
@TestMetadata("incremental.kt")
public void testIncremental() throws Exception {
runTest("js/js.translator/testData/box/main/incremental.kt");
}
@TestMetadata("noArgs.kt")
public void testNoArgs() throws Exception {
runTest("js/js.translator/testData/box/main/noArgs.kt");
}
@TestMetadata("simple.kt")
public void testSimple() throws Exception {
runTest("js/js.translator/testData/box/main/simple.kt");
}
@TestMetadata("suspendMain.kt")
public void testSuspendMain() throws Exception {
runTest("js/js.translator/testData/box/main/suspendMain.kt");
}
@TestMetadata("suspendMainNoArgs.kt")
public void testSuspendMainNoArgs() throws Exception {
runTest("js/js.translator/testData/box/main/suspendMainNoArgs.kt");
}
@TestMetadata("suspendMainThrows.kt")
public void testSuspendMainThrows() throws Exception {
runTest("js/js.translator/testData/box/main/suspendMainThrows.kt");
}
@TestMetadata("twoMains.kt")
public void testTwoMains() throws Exception {
runTest("js/js.translator/testData/box/main/twoMains.kt");
}
}
@TestMetadata("js/js.translator/testData/box/kotlin.test")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Kotlin_test extends AbstractJsTranslatorWasmTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest0(this::doTest, TargetBackend.WASM, testDataFilePath);
}
public void testAllFilesPresentInKotlin_test() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/kotlin.test"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true);
}
@TestMetadata("beforeAfter.kt")
public void testBeforeAfter() throws Exception {
runTest("js/js.translator/testData/box/kotlin.test/beforeAfter.kt");
}
@TestMetadata("ignore.kt")
public void testIgnore() throws Exception {
runTest("js/js.translator/testData/box/kotlin.test/ignore.kt");
}
@TestMetadata("illegalParameters.kt")
public void testIllegalParameters() throws Exception {
runTest("js/js.translator/testData/box/kotlin.test/illegalParameters.kt");
}
@TestMetadata("incremental.kt")
public void testIncremental() throws Exception {
runTest("js/js.translator/testData/box/kotlin.test/incremental.kt");
}
@TestMetadata("inherited.kt")
public void testInherited() throws Exception {
runTest("js/js.translator/testData/box/kotlin.test/inherited.kt");
}
@TestMetadata("mpp.kt")
public void testMpp() throws Exception {
runTest("js/js.translator/testData/box/kotlin.test/mpp.kt");
}
@TestMetadata("nested.kt")
public void testNested() throws Exception {
runTest("js/js.translator/testData/box/kotlin.test/nested.kt");
}
@TestMetadata("returnTestResult.kt")
public void testReturnTestResult() throws Exception {
runTest("js/js.translator/testData/box/kotlin.test/returnTestResult.kt");
}
@TestMetadata("simple.kt")
public void testSimple() throws Exception {
runTest("js/js.translator/testData/box/kotlin.test/simple.kt");
}
}
}
@@ -1,77 +0,0 @@
/*
* 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.
*/
package org.jetbrains.kotlin.js.test.wasm.semantics;
import com.intellij.testFramework.TestDataPath;
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
import org.jetbrains.kotlin.test.KotlinTestUtils;
import org.jetbrains.kotlin.test.util.KtTestUtil;
import org.jetbrains.kotlin.test.TargetBackend;
import org.jetbrains.kotlin.test.TestMetadata;
import org.junit.runner.RunWith;
import java.io.File;
import java.util.regex.Pattern;
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all")
@TestMetadata("js/js.translator/testData/box/kotlin.test")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public class KotlinTestBoxWasmTestGenerated extends AbstractKotlinTestBoxWasmTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest0(this::doTest, TargetBackend.WASM, testDataFilePath);
}
public void testAllFilesPresentInKotlin_test() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/kotlin.test"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true);
}
@TestMetadata("beforeAfter.kt")
public void testBeforeAfter() throws Exception {
runTest("js/js.translator/testData/box/kotlin.test/beforeAfter.kt");
}
@TestMetadata("ignore.kt")
public void testIgnore() throws Exception {
runTest("js/js.translator/testData/box/kotlin.test/ignore.kt");
}
@TestMetadata("illegalParameters.kt")
public void testIllegalParameters() throws Exception {
runTest("js/js.translator/testData/box/kotlin.test/illegalParameters.kt");
}
@TestMetadata("incremental.kt")
public void testIncremental() throws Exception {
runTest("js/js.translator/testData/box/kotlin.test/incremental.kt");
}
@TestMetadata("inherited.kt")
public void testInherited() throws Exception {
runTest("js/js.translator/testData/box/kotlin.test/inherited.kt");
}
@TestMetadata("mpp.kt")
public void testMpp() throws Exception {
runTest("js/js.translator/testData/box/kotlin.test/mpp.kt");
}
@TestMetadata("nested.kt")
public void testNested() throws Exception {
runTest("js/js.translator/testData/box/kotlin.test/nested.kt");
}
@TestMetadata("returnTestResult.kt")
public void testReturnTestResult() throws Exception {
runTest("js/js.translator/testData/box/kotlin.test/returnTestResult.kt");
}
@TestMetadata("simple.kt")
public void testSimple() throws Exception {
runTest("js/js.translator/testData/box/kotlin.test/simple.kt");
}
}
+1 -2
View File
@@ -4,8 +4,7 @@
var ok: String = "fail"
fun main(args: Array<String>) {
assertEquals(1, args.size)
assertEquals("testArg", args[0])
if (0 != args.size) error("fail")
ok = "OK"
}
+2 -3
View File
@@ -8,8 +8,7 @@ var ok: String = "fail"
var callback: () -> Unit = {}
suspend fun main(args: Array<String>) {
assertEquals(1, args.size)
assertEquals("testArg", args[0])
if (0 != args.size) error("Fail")
suspendCoroutine<Unit> { cont ->
callback = {
@@ -21,7 +20,7 @@ suspend fun main(args: Array<String>) {
}
fun box(): String {
assertEquals("fail", ok)
if ("fail" != ok) return "Fail"
callback()
return ok
}
+1 -1
View File
@@ -18,7 +18,7 @@ suspend fun main() {
}
fun box(): String {
assertEquals("fail", ok)
if ("fail" != ok) error("Fail")
callback()
return ok
}
+1 -1
View File
@@ -22,7 +22,7 @@ fun box(): String {
try {
callback()
} catch (e: Exception) {
assertTrue(e === exception)
if (e !== exception) return "Fail"
}
return "OK"
+1 -2
View File
@@ -9,8 +9,7 @@ fun main() {
}
fun main(args: Array<String>) {
assertEquals(1, args.size)
assertEquals("testArg", args[0])
if (args.size != 0) error("Fail")
o = "O"
}
@@ -62,3 +62,9 @@ internal fun <R, P, T> startCoroutineUninterceptedOrReturnIntrinsic2(
): Any? {
implementedAsIntrinsic
}
@PublishedApi
@SinceKotlin("1.3")
internal val EmptyContinuation = Continuation<Any?>(EmptyCoroutineContext) { result ->
result.getOrThrow()
}