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,6 +99,7 @@ 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);
if (callSiteId >= 0) {
CallSite callSite = findCallSiteById(callSiteId, stackFrame); CallSite callSite = findCallSiteById(callSiteId, stackFrame);
ExceptionHandler handler = callSite.firstHandler; ExceptionHandler handler = callSite.firstHandler;
@ -112,6 +113,7 @@ public final class ExceptionHandling {
} }
ShadowStack.setExceptionHandlerId(stackFrame, callSiteId - 1); ShadowStack.setExceptionHandlerId(stackFrame, callSiteId - 1);
}
stackFrame = ShadowStack.getNextStackFrame(stackFrame); stackFrame = ShadowStack.getNextStackFrame(stackFrame);
} }
@ -151,6 +153,7 @@ 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);
if (callSiteId >= 0) {
CallSite callSite = findCallSiteById(callSiteId, stackFrame); CallSite callSite = findCallSiteById(callSiteId, stackFrame);
CallSiteLocation location = callSite.location; CallSiteLocation location = callSite.location;
if (isObfuscated() || location == null) { if (isObfuscated() || location == null) {
@ -161,6 +164,7 @@ public final class ExceptionHandling {
location = location.next; location = location.next;
} }
} }
}
stackFrame = ShadowStack.getNextStackFrame(stackFrame); stackFrame = ShadowStack.getNextStackFrame(stackFrame);
} }
@ -179,6 +183,7 @@ 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);
if (callSiteId >= 0) {
CallSite callSite = findCallSiteById(callSiteId, stackFrame); CallSite callSite = findCallSiteById(callSiteId, stackFrame);
CallSiteLocation location = callSite.location; CallSiteLocation location = callSite.location;
if (isObfuscated()) { if (isObfuscated()) {
@ -202,6 +207,7 @@ public final class ExceptionHandling {
location = location.next; location = location.next;
} }
} }
}
stackFrame = ShadowStack.getNextStackFrame(stackFrame); stackFrame = ShadowStack.getNextStackFrame(stackFrame);
} }
ShadowStack.releaseStack(1); ShadowStack.releaseStack(1);

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) {