Skip to content

Commit

Permalink
Merge pull request #26 from Anamorphosee/release/2.3.8
Browse files Browse the repository at this point in the history
Release/2.3.8
  • Loading branch information
Anamorphosee committed Dec 9, 2023
2 parents 1000c85 + 011ff1d commit 39bf0c9
Show file tree
Hide file tree
Showing 11 changed files with 51 additions and 38 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,3 @@
.idea
build
local.properties
/stacktrace-decoroutinator-android/src/main/resources/decoroutinatorBaseContinuation.dex
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,9 @@ Thus, if the coroutine throws an exception, they mimic the real call stack of th

### JVM
There are three ways to enable Stacktrace-decoroutinator for JVM.
1. (recommended) Add dependency `dev.reformator.stacktracedecoroutinator:stacktrace-decoroutinator-jvm:2.3.7` and call method `DecoroutinatorRuntime.load()`.
2. Add `-javaagent:stacktrace-decoroutinator-jvm-agent-2.3.7.jar` to your JVM start arguments. Corresponding dependency is `dev.reformator.stacktracedecoroutinator:stacktrace-decoroutinator-jvm-agent:2.3.7`.
3. (less recommended) Add dependency `dev.reformator.stacktracedecoroutinator:stacktrace-decoroutinator-jvm-legacy:2.3.7` and call method `DecoroutinatorRuntime.load()`. This way doesn't use Java instrumentation API unlike the way number 1.
1. (recommended) Add dependency `dev.reformator.stacktracedecoroutinator:stacktrace-decoroutinator-jvm:2.3.8` and call method `DecoroutinatorRuntime.load()`.
2. Add `-javaagent:stacktrace-decoroutinator-jvm-agent-2.3.8.jar` to your JVM start arguments. Corresponding dependency is `dev.reformator.stacktracedecoroutinator:stacktrace-decoroutinator-jvm-agent:2.3.8`.
3. (less recommended) Add dependency `dev.reformator.stacktracedecoroutinator:stacktrace-decoroutinator-jvm-legacy:2.3.8` and call method `DecoroutinatorRuntime.load()`. This way doesn't use Java instrumentation API unlike the way number 1.

Usage example:
```kotlin
Expand Down Expand Up @@ -152,7 +152,7 @@ java.lang.Exception: exception at 1653565535416
```

### Android
To enable Stacktrace-decoroutinator for Android you should add dependency `dev.reformator.stacktracedecoroutinator:stacktrace-decoroutinator-android:2.3.7` in your Android application and call method `DecoroutinatorRuntime.load()` before creating any coroutines.
To enable Stacktrace-decoroutinator for Android you should add dependency `dev.reformator.stacktracedecoroutinator:stacktrace-decoroutinator-android:2.3.8` in your Android application and call method `DecoroutinatorRuntime.load()` before creating any coroutines.

It's recomended to add `DecoroutinatorRuntime.load()` call in your `Application.onCreate()` method. Example:
```kotlin
Expand Down
4 changes: 2 additions & 2 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ buildscript {
}
}
dependencies {
classpath("com.android.tools.build:gradle:7.0.4")
classpath("com.android.tools.build:gradle:8.2.0")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.22")
classpath("gradle.plugin.com.github.johnrengelman:shadow:7.1.2")
}
}

subprojects {
group = "dev.reformator.stacktracedecoroutinator"
version = "2.3.7"
version = "2.3.8"
}
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package dev.reformator.stacktracedecoroutinator.android.utils

import android.util.Base64

internal val baseContinuationDexBody: ByteArray = Base64.decode("$CONTENT$", Base64.DEFAULT)
42 changes: 21 additions & 21 deletions stacktrace-decoroutinator-android/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
import java.util.*

plugins {
id("com.android.library")
id("kotlin-android")
`maven-publish`
signing
}

val baseContinuationDexSourcesDir = layout.buildDirectory.get()
.dir("generated")
.dir("baseContinuationDexSources")
.asFile

android {
compileSdk = 26

Expand All @@ -21,6 +28,12 @@ android {
kotlinOptions {
jvmTarget = "1.8"
}

sourceSets {
android.sourceSets["main"].java.srcDir(baseContinuationDexSourcesDir)
}

namespace = "dev.reformator.stacktracedecoroutinator"
}

repositories {
Expand All @@ -39,18 +52,10 @@ dependencies {
androidTestImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:${properties["kotlinxCoroutinesVersion"]}")
}

val baseContinuationDexFile =
projectDir
.resolve("src")
.resolve("main")
.resolve("resources")
.resolve("decoroutinatorBaseContinuation.dex")

val generateBaseContinuationDexTask = task("generateBaseContinuationDex") {
val generateBaseContinuationDexSourcesTask = task("generateBaseContinuationDexSources") {
dependsOn(":stdlib:jar")
doLast {
baseContinuationDexFile.delete()
val destFolder = baseContinuationDexFile.parent
baseContinuationDexSourcesDir.deleteRecursively()
val tmpDir = temporaryDir
val jarFile = project(":stdlib")
.tasks
Expand All @@ -67,21 +72,16 @@ val generateBaseContinuationDexTask = task("generateBaseContinuationDex") {
jarFile.absolutePath
)
}
copy {
from(tmpDir)
into(destFolder)
include("classes.dex")
rename("classes.dex", baseContinuationDexFile.name)
}
baseContinuationDexSourcesDir.mkdirs()
file(baseContinuationDexSourcesDir.resolve("baseContinuationContent.kt")).writeText(
file(projectDir.resolve("baseContinuationContent.ktTemplate")).readText()
.replace("\$CONTENT\$", Base64.getEncoder().encodeToString(tmpDir.resolve("classes.dex").readBytes()))
)
}
}

tasks.clean {
delete(baseContinuationDexFile)
}

tasks.named("preBuild") {
dependsOn(generateBaseContinuationDexTask)
dependsOn(generateBaseContinuationDexSourcesTask)
}

val androidJavadocs = task("androidJavadocs", Javadoc::class) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="dev.reformator.stacktracedecoroutinator">
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application android:name="dev.reformator.stacktracedecoroutinator.utils.DecoroutinatorApplication"/>
</manifest>
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package dev.reformator.stacktracedecoroutinator.runtime
import dalvik.system.BaseDexClassLoader
import dalvik.system.InMemoryDexClassLoader
import dev.reformator.stacktracedecoroutinator.android.DecoroutinatorAndroidStacktraceMethodHandleRegistryImpl
import dev.reformator.stacktracedecoroutinator.android.utils.baseContinuationDexBody
import dev.reformator.stacktracedecoroutinator.common.*
import java.lang.reflect.Field
import java.nio.ByteBuffer
Expand Down Expand Up @@ -34,10 +35,7 @@ object DecoroutinatorRuntime {
val dexElements = dexElementsField[pathList] as Array<Any>

val decoroutinatorDexElements = run {
val dexBody = loader.getResourceAsStream("decoroutinatorBaseContinuation.dex").use{
it.readBytes()
}
val dexClassLoader = InMemoryDexClassLoader(ByteBuffer.wrap(dexBody), null)
val dexClassLoader = InMemoryDexClassLoader(ByteBuffer.wrap(baseContinuationDexBody), null)
val pathList = pathListField[dexClassLoader]
dexElementsField[pathList] as Array<Any>
}
Expand Down
1 change: 1 addition & 0 deletions stacktrace-decoroutinator-jvm-legacy/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ dependencies {
tasks.test {
useJUnitPlatform()
systemProperty("kotlinx.coroutines.stacktrace.recovery", "false")
jvmArgs("--add-opens", "java.base/java.lang=ALL-UNNAMED")
}

tasks.withType<KotlinCompile> {
Expand Down
11 changes: 10 additions & 1 deletion stdlib/src/main/kotlin/continuation-stdlib.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ import dev.reformator.stacktracedecoroutinator.common.DecoroutinatorMarker
import dev.reformator.stacktracedecoroutinator.common.decoroutinatorRegistry
import dev.reformator.stacktracedecoroutinator.common.JavaUtilsImpl
import dev.reformator.stacktracedecoroutinator.stdlib.decoroutinatorResumeWith
import dev.reformator.stacktracedecoroutinator.stdlib.invokeSuspendFunc
import java.io.Serializable
import java.lang.invoke.MethodHandle
import java.lang.invoke.MethodHandles
import java.lang.invoke.MethodType
import kotlin.coroutines.Continuation
import kotlin.coroutines.intrinsics.COROUTINE_SUSPENDED

Expand All @@ -15,9 +19,14 @@ internal abstract class BaseContinuationImpl(
): Continuation<Any?>, CoroutineStackFrame, Serializable {
final override fun resumeWith(result: Result<Any?>) {
if (decoroutinatorRegistry.enabled) {
val invokeSuspendFuncLocal: MethodHandle = invokeSuspendFunc ?: run {
val result = MethodHandles.lookup().findVirtual(BaseContinuationImpl::class.java, "invokeSuspend", MethodType.methodType(Object::class.java, Object::class.java))
invokeSuspendFunc = result
result
}
decoroutinatorResumeWith(
result,
invokeSuspendFunc = { invokeSuspend(it) },
invokeSuspendFunc = invokeSuspendFuncLocal,
releaseInterceptedFunc = { releaseIntercepted() }
)
} else {
Expand Down
6 changes: 4 additions & 2 deletions stdlib/src/main/kotlin/stdlib.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ import kotlin.coroutines.Continuation
import kotlin.coroutines.intrinsics.COROUTINE_SUSPENDED
import kotlin.coroutines.jvm.internal.BaseContinuationImpl

var invokeSuspendFunc: MethodHandle? = null

internal fun BaseContinuationImpl.decoroutinatorResumeWith(
result: Result<Any?>,
invokeSuspendFunc: BaseContinuationImpl.(Result<Any?>) -> Any?,
invokeSuspendFunc: MethodHandle,
releaseInterceptedFunc: BaseContinuationImpl.() -> Unit
) {
val baseContinuations = buildList {
Expand All @@ -33,7 +35,7 @@ internal fun BaseContinuationImpl.decoroutinatorResumeWith(
val continuation = baseContinuations[index]
JavaUtilsImpl.probeCoroutineResumed(continuation)
val newResult = try {
val newResult = continuation.invokeSuspendFunc(Result.success(result))
val newResult = invokeSuspendFunc.invokeExact(continuation, result)
if (newResult === COROUTINE_SUSPENDED) {
return@BiFunction COROUTINE_SUSPENDED
}
Expand Down

0 comments on commit 39bf0c9

Please sign in to comment.