Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ffi] Failing to bind malloc() and free() in libc #191

Open
shirakaba opened this issue Aug 17, 2024 · 1 comment
Open

[ffi] Failing to bind malloc() and free() in libc #191

shirakaba opened this issue Aug 17, 2024 · 1 comment

Comments

@shirakaba
Copy link

shirakaba commented Aug 17, 2024

I'm trying to use objc_getClassList(::) via Porffor's experimental FFI library. Here's an example of using it in C:

int numClasses;
Class * classes = NULL;
 
classes = NULL;
numClasses = objc_getClassList(NULL, 0);
 
if (numClasses > 0 )
{
    classes = malloc(sizeof(Class) * numClasses);
    numClasses = objc_getClassList(classes, numClasses);
    free(classes);
}

I'm referring to NodObjC, which demonstrates how to access libc and libobjc APIs via ffi-napi.

(Another more modern effort, objc also exists.)

Here's what I've got so far:

/// <reference types="porffor/compiler/builtins/porffor" />

const { malloc, free } = (Porffor as any).dlopen("libc.dylib", {
  malloc: { result: "pointer", parameters: ["size_t"] },
  free: { result: "void", parameters: ["pointer"] },
});

const { objc_getClassList } = (Porffor as any).dlopen("libobjc.dylib", {
  objc_getClassList: { result: "i32", parameters: ["pointer", "i32"] },
});

// FIXME: need to be able to express: sizeof(Class).
// For now we're hard-coding it based on:
// https://github.com/TooTallNate/NodObjC/blob/e4710fb8b73d3a2860de1e959e335a6de3e2191c/test/archive/core/getClassList.js#L13
const sizeofClass = 8;
const numClasses = objc_getClassList(null, 0);
const classes = malloc(numClasses * sizeofClass);
objc_getClassList(classes, 0);

console.log("Classes:", classes);
// TODO: Loop over Class*. Will require support for pointer manipulation like this:
// https://github.com/TooTallNate/NodObjC/blob/e4710fb8b73d3a2860de1e959e335a6de3e2191c/test/archive/core/getClassList.js#L13

free(classes);

It actually compiles if you leave out the malloc() and free() usages and just evaluate numClasses. But with the full example above, I'm getting some compilation errors:

porf --native dist/index.js

porffor_tmp.c:59:15: error: unknown type name 'undefined'
i32 (*malloc)(undefined l0);
              ^
porffor_tmp.c:59:7: error: redefinition of 'malloc' as different kind of symbol
i32 (*malloc)(undefined l0);
      ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/malloc/_malloc.h:54:7: note: previous definition is here
void *malloc(size_t __size) __result_use_check __alloc_size(1) _MALLOC_TYPED(malloc_type_malloc, 1);
      ^
porffor_tmp.c:60:13: error: unknown type name 'undefined'
i32 (*free)(undefined l0);
            ^
porffor_tmp.c:60:7: error: redefinition of 'free' as different kind of symbol
i32 (*free)(undefined l0);
      ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/malloc/_malloc.h:56:7: note: previous definition is here
void  free(void * __unsafe_indexable);
      ^
porffor_tmp.c:10190:9: error: redefinition of '_dl'
  void* _dl = dlopen("libobjc.dylib", RTLD_LAZY);
        ^
porffor_tmp.c:10187:9: note: previous definition is here
  void* _dl = dlopen("libc.dylib", RTLD_LAZY);
        ^
porffor_tmp.c:10196:11: error: assigning to 'f64' (aka 'double') from incompatible type 'void *'
  classes = (*malloc)((i32)(numClasses * sizeofClass));
          ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6 errors generated.
Error: Command failed: clang porffor_tmp.c -o ./porffor_tmp -Ofast -flto=thin -march=native -s -ffast-math -fno-exceptions -fno-ident -fno-asynchronous-unwind-tables -ffunction-sections -fdata-sections
@Rob23oba
Copy link

size_t and void are currently not types supported by porffor, you might be able to use u64 and undefined instead

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants