C: fix exception when marshalling string from native code to Java and GC is triggered

This commit is contained in:
Alexey Andreev 2019-11-05 18:14:09 +03:00
parent c05f40cc6a
commit 3335b86619
2 changed files with 69 additions and 39 deletions

View File

@ -99,19 +99,21 @@ public final class ExceptionHandling {
int handlerId = 0;
stackLoop: while (stackFrame != null) {
int callSiteId = ShadowStack.getCallSiteId(stackFrame);
CallSite callSite = findCallSiteById(callSiteId, stackFrame);
ExceptionHandler handler = callSite.firstHandler;
if (callSiteId >= 0) {
CallSite callSite = findCallSiteById(callSiteId, stackFrame);
ExceptionHandler handler = callSite.firstHandler;
while (handler != null) {
if (handler.exceptionClass == null || handler.exceptionClass.isSupertypeOf.apply(exceptionClass)) {
handlerId = handler.id;
ShadowStack.setExceptionHandlerId(stackFrame, handler.id);
break stackLoop;
while (handler != null) {
if (handler.exceptionClass == null || handler.exceptionClass.isSupertypeOf.apply(exceptionClass)) {
handlerId = handler.id;
ShadowStack.setExceptionHandlerId(stackFrame, handler.id);
break stackLoop;
}
handler = handler.next;
}
handler = handler.next;
}
ShadowStack.setExceptionHandlerId(stackFrame, callSiteId - 1);
ShadowStack.setExceptionHandlerId(stackFrame, callSiteId - 1);
}
stackFrame = ShadowStack.getNextStackFrame(stackFrame);
}
@ -151,14 +153,16 @@ public final class ExceptionHandling {
int size = 0;
while (stackFrame != null) {
int callSiteId = ShadowStack.getCallSiteId(stackFrame);
CallSite callSite = findCallSiteById(callSiteId, stackFrame);
CallSiteLocation location = callSite.location;
if (isObfuscated() || location == null) {
size++;
} else {
while (location != null) {
if (callSiteId >= 0) {
CallSite callSite = findCallSiteById(callSiteId, stackFrame);
CallSiteLocation location = callSite.location;
if (isObfuscated() || location == null) {
size++;
location = location.next;
} else {
while (location != null) {
size++;
location = location.next;
}
}
}
@ -179,27 +183,29 @@ public final class ExceptionHandling {
int index = 0;
while (stackFrame != null) {
int callSiteId = ShadowStack.getCallSiteId(stackFrame);
CallSite callSite = findCallSiteById(callSiteId, stackFrame);
CallSiteLocation location = callSite.location;
if (isObfuscated()) {
target[index++] = new StackTraceElement("Obfuscated", "obfuscated", "Obfuscated.java", callSiteId);
} else if (location == null) {
target[index++] = new StackTraceElement("", "", null, -1);
} else {
while (location != null) {
MethodLocation methodLocation = location.method;
StackTraceElement element;
if (methodLocation != null) {
element = new StackTraceElement(
methodLocation.className != null ? methodLocation.className.value : "",
methodLocation.methodName != null ? methodLocation.methodName.value : "",
methodLocation.fileName != null ? methodLocation.fileName.value : null,
location.lineNumber);
} else {
element = new StackTraceElement("", "", null, location.lineNumber);
if (callSiteId >= 0) {
CallSite callSite = findCallSiteById(callSiteId, stackFrame);
CallSiteLocation location = callSite.location;
if (isObfuscated()) {
target[index++] = new StackTraceElement("Obfuscated", "obfuscated", "Obfuscated.java", callSiteId);
} else if (location == null) {
target[index++] = new StackTraceElement("", "", null, -1);
} else {
while (location != null) {
MethodLocation methodLocation = location.method;
StackTraceElement element;
if (methodLocation != null) {
element = new StackTraceElement(
methodLocation.className != null ? methodLocation.className.value : "",
methodLocation.methodName != null ? methodLocation.methodName.value : "",
methodLocation.fileName != null ? methodLocation.fileName.value : null,
location.lineNumber);
} else {
element = new StackTraceElement("", "", null, location.lineNumber);
}
target[index++] = element;
location = location.next;
}
target[index++] = element;
location = location.next;
}
}
stackFrame = ShadowStack.getNextStackFrame(stackFrame);

View File

@ -1,6 +1,12 @@
#include "string.h"
#include "stack.h"
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
#if TEAVM_INCREMENTAL
#define TEAVM_ALLOC_STACK(sz) TEAVM_ALLOC_STACK_DEF(sz, NULL)
#endif
int32_t teavm_hashCode(TeaVM_String* string) {
int32_t hashCode = INT32_C(0);
@ -106,9 +112,15 @@ TeaVM_String* teavm_cToString(char* cstring) {
return NULL;
}
TEAVM_ALLOC_STACK(1);
TEAVM_CALL_SITE(-1);
TEAVM_GC_ROOT_RELEASE(0);
size_t clen = strlen(cstring);
int32_t size = teavm_c16Size(cstring, clen);
TeaVM_Array* charArray = teavm_allocateCharArray(size);
TEAVM_GC_ROOT(0, charArray);
char16_t* javaChars = TEAVM_ARRAY_DATA(charArray, char16_t);
mbstate_t state = {0};
for (int32_t i = 0; i < size; ++i) {
@ -120,7 +132,10 @@ TeaVM_String* teavm_cToString(char* cstring) {
cstring += result;
}
}
return teavm_createString(charArray);
TeaVM_String* result = teavm_createString(charArray);
TEAVM_RELEASE_STACK;
return result;
}
TeaVM_String* teavm_c16ToString(char16_t* cstring) {
@ -128,14 +143,23 @@ TeaVM_String* teavm_c16ToString(char16_t* cstring) {
return NULL;
}
TEAVM_ALLOC_STACK(1);
TEAVM_CALL_SITE(-1);
TEAVM_GC_ROOT_RELEASE(0);
int32_t size = 0;
while (cstring[size] != 0) {
++size;
}
TeaVM_Array* charArray = teavm_allocateCharArray(size);
TEAVM_GC_ROOT(0, charArray);
char16_t* javaChars = TEAVM_ARRAY_DATA(charArray, char16_t);
memcpy(javaChars, cstring, size * sizeof(char16_t));
return teavm_createString(charArray);
TeaVM_String* result = teavm_createString(charArray);
TEAVM_RELEASE_STACK;
return result;
}
char16_t* teavm_mbToChar16(char* cstring, int32_t* length) {