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

View File

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