mirror of
https://github.com/janet-lang/janet
synced 2025-07-04 02:52:59 +00:00
Improve sysv64 classify algorithm.
This commit is contained in:
parent
3479841c77
commit
f33c381043
@ -602,7 +602,7 @@ static JanetFFIMapping void_mapping(void) {
|
|||||||
#ifdef JANET_FFI_SYSV64_ENABLED
|
#ifdef JANET_FFI_SYSV64_ENABLED
|
||||||
/* AMD64 ABI Draft 0.99.7 – November 17, 2014 – 15:08
|
/* AMD64 ABI Draft 0.99.7 – November 17, 2014 – 15:08
|
||||||
* See section 3.2.3 Parameter Passing */
|
* See section 3.2.3 Parameter Passing */
|
||||||
static JanetFFIWordSpec sysv64_classify(JanetFFIType type) {
|
static JanetFFIWordSpec sysv64_classify_ext(JanetFFIType type, size_t shift) {
|
||||||
switch (type.prim) {
|
switch (type.prim) {
|
||||||
case JANET_FFI_TYPE_PTR:
|
case JANET_FFI_TYPE_PTR:
|
||||||
case JANET_FFI_TYPE_STRING:
|
case JANET_FFI_TYPE_STRING:
|
||||||
@ -629,21 +629,27 @@ static JanetFFIWordSpec sysv64_classify(JanetFFIType type) {
|
|||||||
int has_int_lo = 0;
|
int has_int_lo = 0;
|
||||||
int has_int_hi = 0;
|
int has_int_hi = 0;
|
||||||
for (uint32_t i = 0; i < st->field_count; i++) {
|
for (uint32_t i = 0; i < st->field_count; i++) {
|
||||||
JanetFFIWordSpec next_class = sysv64_classify(st->fields[i].type);
|
JanetFFIWordSpec next_class = sysv64_classify_ext(st->fields[i].type, shift + st->fields[i].offset);
|
||||||
switch (next_class) {
|
switch (next_class) {
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
case JANET_SYSV64_INTEGER:
|
case JANET_SYSV64_INTEGER:
|
||||||
case JANET_SYSV64_PAIR_INTINT:
|
if (shift + st->fields[i].offset + type_size(st->fields[i].type) <= 8) {
|
||||||
case JANET_SYSV64_PAIR_INTSSE:
|
|
||||||
case JANET_SYSV64_PAIR_SSEINT: {
|
|
||||||
/* since everything is aligned, nothing should straddle an 8-byte or be in memory */
|
|
||||||
if (st->fields[i].offset >= 8) {
|
|
||||||
has_int_hi = 2;
|
|
||||||
} else {
|
|
||||||
has_int_lo = 1;
|
has_int_lo = 1;
|
||||||
|
} else {
|
||||||
|
has_int_hi = 2;
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
|
case JANET_SYSV64_PAIR_INTINT:
|
||||||
|
has_int_lo = 1;
|
||||||
|
has_int_hi = 2;
|
||||||
|
break;
|
||||||
|
case JANET_SYSV64_PAIR_INTSSE:
|
||||||
|
has_int_lo = 1;
|
||||||
|
break;
|
||||||
|
case JANET_SYSV64_PAIR_SSEINT:
|
||||||
|
has_int_hi = 2;
|
||||||
|
break;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -664,7 +670,7 @@ static JanetFFIWordSpec sysv64_classify(JanetFFIType type) {
|
|||||||
} else {
|
} else {
|
||||||
/* Normal struct classification */
|
/* Normal struct classification */
|
||||||
for (uint32_t i = 0; i < st->field_count; i++) {
|
for (uint32_t i = 0; i < st->field_count; i++) {
|
||||||
JanetFFIWordSpec next_class = sysv64_classify(st->fields[i].type);
|
JanetFFIWordSpec next_class = sysv64_classify_ext(st->fields[i].type, shift + st->fields[i].offset);
|
||||||
if (next_class != clazz) {
|
if (next_class != clazz) {
|
||||||
if (clazz == JANET_SYSV64_NO_CLASS) {
|
if (clazz == JANET_SYSV64_NO_CLASS) {
|
||||||
clazz = next_class;
|
clazz = next_class;
|
||||||
@ -687,6 +693,9 @@ static JanetFFIWordSpec sysv64_classify(JanetFFIType type) {
|
|||||||
return JANET_SYSV64_NO_CLASS;
|
return JANET_SYSV64_NO_CLASS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
static JanetFFIWordSpec sysv64_classify(JanetFFIType type) {
|
||||||
|
return sysv64_classify_ext(type, 0);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
JANET_CORE_FN(cfun_ffi_signature,
|
JANET_CORE_FN(cfun_ffi_signature,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user