vlang / c2v

C/C++ to V translator
GNU General Public License v3.0
224 stars 30 forks source link

Conversion panic #91

Open wenq1 opened 1 year ago

wenq1 commented 1 year ago

c2v.toml:

[project]
additional_flags = '-DCONFIG_VERSION=\"2021-03-27\"'

Now,

$ git clone https://github.com/bellard/quickjs
$ cd quickjs
$ nano c2v.toml

$ v translate qjsc.c

C to V translator 0.3.1
  translating qjsc.c          ... No more children
No more children
No more children
No more children
No more children
No more children
No more children
No more children
No more children
No more children

Unhandled expr() node {PredefinedExpr} (ast line nr node.ast_line_nr "qjsc.c"):
&Node{
    id: '0x14e1ef938'
    kind_str: 'PredefinedExpr'
    location: NodeLocation{
        offset: 0
        file: ''
        line: 0
        source_file: SourceFile{
            path: ''
        }
        spelling_file: SourceFile{
            path: ''
        }
    }
    range: Range{
        begin: Begin{
            spelling_file: SourceFile{
                path: '/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/assert.h'
            }
        }
    }
    previous_declaration: ''
    name: '__func__'
    ast_type: AstJsonType{
        desugared_qualified: ''
        qualified: 'const char [18]'
    }
    class_modifier: ''
    tags: ''
    initialization_type: ''
    value: ''
    value_number: 0
    opcode: ''
    ast_argument_type: AstJsonType{
        desugared_qualified: ''
        qualified: ''
    }
    array_filler: []
    declaration_id: ''
    label_id: ''
    is_postfix: false
    inner: [Node{
        id: '0x14e1ef908'
        kind_str: 'StringLiteral'
        location: NodeLocation{
            offset: 0
            file: ''
            line: 0
            source_file: SourceFile{
                path: ''
            }
            spelling_file: SourceFile{
                path: ''
            }
        }
        range: Range{
            begin: Begin{
                spelling_file: SourceFile{
                    path: '/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/assert.h'
                }
            }
        }
        previous_declaration: ''
        name: ''
        ast_type: AstJsonType{
            desugared_qualified: ''
            qualified: 'const char [18]'
        }
        class_modifier: ''
        tags: ''
        initialization_type: ''
        value: '"find_unique_cname"'
        value_number: 0
        opcode: ''
        ast_argument_type: AstJsonType{
            desugared_qualified: ''
            qualified: ''
        }
        array_filler: []
        declaration_id: ''
        label_id: ''
        is_postfix: false
        inner: []
        ref_declaration: RefDeclarationNode{
            kind_str: ''
            name: ''
            kind: BAD
        }
        kind: StringLiteral
        current_child_id: 0
        is_builtin_type: false
        redeclarations_count: 0
    }]
    ref_declaration: RefDeclarationNode{
        kind_str: ''
        name: ''
        kind: BAD
    }
    kind: PredefinedExpr
    current_child_id: 0
    is_builtin_type: false
    redeclarations_count: 0
}
0   c2v                                 0x000000010493bbfc main__C2V_expr + 4296
1   c2v                                 0x000000010493a930 main__C2V_fn_call + 1304
2   c2v                                 0x000000010493bdf0 main__C2V_expr + 4796
3   c2v                                 0x000000010493c8cc main__C2V_expr + 7576
4   c2v                                 0x000000010493bae8 main__C2V_expr + 4020
5   c2v                                 0x0000000104942360 main__C2V_statement + 1048
6   c2v                                 0x00000001049402b8 main__C2V_statements + 124
7   c2v                                 0x000000010493d968 main__C2V_fn_decl + 2972
8   c2v                                 0x000000010494a134 main__C2V_top_level + 156
9   c2v                                 0x00000001049498fc main__C2V_translate_file + 2644
10  c2v                                 0x0000000104948db8 main__main + 1236
11  c2v                                 0x000000010494d4bc main + 84
12  dyld                                0x0000000104b650f4 start + 520
C2V command: '/Users/wc/.vmodules/c2v/c2v' 'qjsc.c'
C2V failed to translate the C files. Please report it via GitHub.
ArtemkaKun commented 1 year ago

Repo with C code - https://github.com/bellard/quickjs

wenq1 commented 1 year ago

Temporarily set -DNDEBUG, got the following. C. prefixes can be fixed manually as per #71. What about DynBufReallocFunc? Where does that come from?

[translated]
module main

struct Lldiv_t {
    quot i64
    rem i64
}
fn abort()

fn strtod( &i8,  &&u8) f64

fn strtod( &i8,  &&u8) f64

fn system( &i8) int

fn strcpy( &i8,  &i8) &i8

fn strcpy(__dst &i8, __src &i8) &i8

fn access( &i8,  int) int

fn dup( int) int

fn execv(__path &i8, __argv &&u8) int

fn execvp(__file &i8, __argv &&u8) int

fn fork() Pid_t

fn getpid() Pid_t

fn link( &i8,  &i8) int

fn unlink( &i8) int

fn getopt( int,  &&u8,  &i8) int

[weak]__global ( optarg &i8

)

[weak]__global ( optind int

)

type BOOL = int

const ( // empty enum
    const_false = 0
    const_true = 1
)

fn pstrcpy(buf &i8, buf_size int, str &i8)

fn strstart(str &i8, val &i8, ptr &&u8) int

fn has_suffix(str &i8, suffix &i8) int

struct Packed_u64 {
    v u64
}
struct Packed_u32 {
    v u32
}
struct Packed_u16 {
    v Uint16_t
}
type DynBufReallocFunc = Void *(void *,voidptr, size_t)
struct DynBuf {
    buf &u8
    size usize
    allocated_size usize
    error BOOL
    realloc_func &DynBufReallocFunc
    opaque voidptr
}
type JSClassID = u32
type JSAtom = u32

const ( // empty enum
    js_tag_first = 0
    js_tag_big_decimal = 1
    js_tag_big_int = 2
    js_tag_big_float = 3
    js_tag_symbol = 4
    js_tag_string = 5
    js_tag_module = 6
    js_tag_function_bytecode = 7
    js_tag_object = 8
    js_tag_int = 9
    js_tag_bool = 10
    js_tag_null = 11
    js_tag_undefined = 12
    js_tag_uninitialized = 13
    js_tag_catch_offset = 14
    js_tag_exception = 15
    js_tag_float64 = 16
)

struct JSRefCountHeader {
    ref_count int
}
union JSValueUnion {
    int32 int
    float64 f64
    ptr voidptr
}
struct JSValue {
    u JSValueUnion
    tag i64
}
type JSCFunction = JSValue (JSContext *, JSValue, int, JSValue *)
type JSCFunctionMagic = JSValue (JSContext *, JSValue, int, JSValue *, int)
type JSCFunctionData = JSValue (JSContext *, JSValue, int, JSValue *, int, JSValue *)
struct JSMallocState {
    malloc_count usize
    malloc_size usize
    malloc_limit usize
    opaque voidptr
}
struct JSMallocFunctions {
    js_malloc fn (&JSMallocState, usize) voidptr
    js_free fn (&JSMallocState, voidptr)
    js_realloc fn (&JSMallocState, voidptr, usize) voidptr
    js_malloc_usable_size fn (voidptr) usize
}
[c:'JS_NewRuntime']
fn js_newruntime() &JSRuntime

[c:'JS_SetMaxStackSize']
fn js_setmaxstacksize(rt &JSRuntime, stack_size usize)

[c:'JS_FreeRuntime']
fn js_freeruntime(rt &JSRuntime)

type JS_MarkFunc = Void (JSRuntime *, JSGCObjectHeader *)
[c:'JS_NewContext']
fn js_newcontext(rt &JSRuntime) &JSContext

[c:'JS_FreeContext']
fn js_freecontext(s &JSContext)

[c:'JS_NewContextRaw']
fn js_newcontextraw(rt &JSRuntime) &JSContext

[c:'JS_AddIntrinsicBaseObjects']
fn js_addintrinsicbaseobjects(ctx &JSContext)

[c:'JS_AddIntrinsicBigFloat']
fn js_addintrinsicbigfloat(ctx &JSContext)

[c:'JS_AddIntrinsicBigDecimal']
fn js_addintrinsicbigdecimal(ctx &JSContext)

[c:'JS_AddIntrinsicOperators']
fn js_addintrinsicoperators(ctx &JSContext)

[c:'JS_EnableBignumExt']
fn js_enablebignumext(ctx &JSContext, enable int)

fn js_free(ctx &JSContext, ptr voidptr)

struct JSMemoryUsage {
    malloc_size i64
    malloc_limit i64
    memory_used_size i64
    malloc_count i64
    memory_used_count i64
    atom_count i64
    atom_size i64
    str_count i64
    str_size i64
    obj_count i64
    obj_size i64
    prop_count i64
    prop_size i64
    shape_count i64
    shape_size i64
    js_func_count i64
    js_func_size i64
    js_func_code_size i64
    js_func_pc2line_count i64
    js_func_pc2line_size i64
    c_func_count i64
    array_count i64
    fast_array_count i64
    fast_array_elements i64
    binary_object_count i64
    binary_object_size i64
}
struct JSPropertyEnum {
    is_enumerable int
    atom JSAtom
}
struct JSPropertyDescriptor {
    flags int
    value JSValue
    getter JSValue
    setter JSValue
}
struct JSClassExoticMethods {
    get_own_property fn (&JSContext, &JSPropertyDescriptor, JSValue, JSAtom) int
    get_own_property_names fn (&JSContext, &&JSPropertyEnum, &u32, JSValue) int
    delete_property fn (&JSContext, JSValue, JSAtom) int
    define_own_property fn (&JSContext, JSValue, JSAtom, JSValue, JSValue, JSValue, int) int
    has_property fn (&JSContext, JSValue, JSAtom) int
    get_property fn (&JSContext, JSValue, JSAtom, JSValue) JSValue
    set_property fn (&JSContext, JSValue, JSAtom, JSValue, JSValue, int) int
}
type JSClassFinalizer = Void (JSRuntime *, JSValue)
type JSClassGCMark = Void (JSRuntime *, JSValue, JS_MarkFunc *)
type JSClassCall = JSValue (JSContext *, JSValue, JSValue, int, JSValue *, int)
struct JSClassDef {
    class_name &i8
    finalizer &JSClassFinalizer
    gc_mark &JSClassGCMark
    call &JSClassCall
    exotic &JSClassExoticMethods
}
[c:'JS_IsException']
fn js_isexception(v JSValue) int {
    return __builtin_expect(!!((int((v).tag)) == js_tag_exception), 0)
}

[c:'JS_Throw']
fn js_throw(ctx &JSContext, obj JSValue) JSValue

[c2v_variadic]
[c:'JS_ThrowReferenceError']
fn js_throwreferenceerror(ctx &JSContext, fmt &i8) JSValue

[c:'JS_FreeValue']
fn js_freevalue(ctx &JSContext, v JSValue)  {
    if (u32((int((v).tag))) >= u32(js_tag_first)) {
        p := &JSRefCountHeader(((v).u.ptr))
        if p.ref_count --$ <= 0 {
            __js_freevalue(ctx, v)
        }
    }
}

[c:'JS_DetectModule']
fn js_detectmodule(input &i8, input_len usize) int

[c:'JS_Eval']
fn js_eval(ctx &JSContext, input &i8, input_len usize, filename &i8, eval_flags int) JSValue

type JSFreeArrayBufferDataFunc = Void (JSRuntime *,voidptr,voidptr)
struct JSSharedArrayBufferFunctions {
    sab_alloc fn (voidptr, usize) voidptr
    sab_free fn (voidptr, voidptr)
    sab_dup fn (voidptr, voidptr)
    sab_opaque voidptr
}
type JSHostPromiseRejectionTracker = Void (JSContext *, JSValue, JSValue, int,voidptr)
type JSInterruptHandler = Int (JSRuntime *,voidptr)
type JSModuleNormalizeFunc = Char *(JSContext *, char *, char *,voidptr)
type JSModuleLoaderFunc = JSModuleDef *(JSContext *, char *,voidptr)
[c:'JS_SetModuleLoaderFunc']
fn js_setmoduleloaderfunc(rt &JSRuntime, module_normalize &JSModuleNormalizeFunc, module_loader &JSModuleLoaderFunc, opaque voidptr)

type JSJobFunc = JSValue (JSContext *, int, JSValue *)
[c:'JS_WriteObject']
fn js_writeobject(ctx &JSContext, psize &usize, obj JSValue, flags int) &u8

enum JSCFunctionEnum {
    js_cfunc_generic
    js_cfunc_generic_magic
    js_cfunc_constructor
    js_cfunc_constructor_magic
    js_cfunc_constructor_or_func
    js_cfunc_constructor_or_func_magic
    js_cfunc_f_f
    js_cfunc_f_f_f
    js_cfunc_getter
    js_cfunc_setter
    js_cfunc_getter_magic
    js_cfunc_setter_magic
    js_cfunc_iterator_next
}

union JSCFunctionType {
    generic &JSCFunction
    generic_magic fn (&JSContext, JSValue, int, &JSValue, int) JSValue
    constructor &JSCFunction
    constructor_magic fn (&JSContext, JSValue, int, &JSValue, int) JSValue
    constructor_or_func &JSCFunction
    f_f fn (f64) f64
    f_f_f fn (f64, f64) f64
    getter fn (&JSContext, JSValue) JSValue
    setter fn (&JSContext, JSValue, JSValue) JSValue
    getter_magic fn (&JSContext, JSValue, int) JSValue
    setter_magic fn (&JSContext, JSValue, JSValue, int) JSValue
    iterator_next fn (&JSContext, JSValue, int, &JSValue, &int, int) JSValue
}
struct JSCFunctionListEntry {
    name &i8
    prop_flags u8
    def_type u8
    magic i16
    u Union (unnamed union at ../quickjs.h
}
type JSModuleInitFunc = Int (JSContext *, JSModuleDef *)
[c:'JS_NewCModule']
fn js_newcmodule(ctx &JSContext, name_str &i8, func &JSModuleInitFunc) &JSModuleDef

fn js_std_add_helpers(ctx &JSContext, argc int, os.argv &&u8)

fn js_std_loop(ctx &JSContext)

fn js_std_init_handlers(rt &JSRuntime)

fn js_std_dump_error(ctx &JSContext)

fn js_load_file(ctx &JSContext, pbuf_len &usize, filename &i8) &u8

fn js_module_loader(ctx &JSContext, module_name &i8, opaque voidptr) &JSModuleDef

fn js_std_eval_binary(ctx &JSContext, buf &u8, buf_len usize, flags int)

fn js_std_set_worker_new_context_func(func fn (&JSRuntime) &JSContext)

struct Namelist_entry_t {
    name &i8
    short_name &i8
    flags int
}
struct Namelist_t {
    array &Namelist_entry_t
    count int
    size int
}
struct FeatureEntry {
    option_name &i8
    init_name &i8
}
[weak]__global ( cname_list Namelist_t

)

[weak]__global ( cmodule_list Namelist_t

)

[weak]__global ( init_module_list Namelist_t

)

[weak]__global ( feature_bitmap u64

)

[weak]__global ( outfile &C.FILE

)

[weak]__global ( byte_swap BOOL

)

[weak]__global ( dynamic_export BOOL

)

[export:'c_ident_prefix']
const (
c_ident_prefix   = c'qjsc_'
)

[export:'feature_list']
const (
feature_list   = [FeatureEntry {
c'date', c'Date'}
, FeatureEntry {
c'eval', c'Eval'}
, FeatureEntry {
c'string-normalize', c'StringNormalize'}
, FeatureEntry {
c'regexp', c'RegExp'}
, FeatureEntry {
c'json', c'JSON'}
, FeatureEntry {
c'proxy', c'Proxy'}
, FeatureEntry {
c'map', c'MapSet'}
, FeatureEntry {
c'typedarray', c'TypedArrays'}
, FeatureEntry {
c'promise', c'Promise'}
, FeatureEntry {
c'module-loader', (voidptr(0))}
]!

)

fn namelist_add(lp &Namelist_t, name &i8, short_name &i8, flags int)  {
    e := &Namelist_entry_t(0)
    if lp.count == lp.size {
        newsize := lp.size + (lp.size >> 1) + 4
        a := realloc(lp.array, sizeof(lp.array [0] ) * newsize)
        lp.array = a
        lp.size = newsize
    }
    e = &lp.array [lp.count ++]
    e.name = C.strdup(name)
    if short_name {
    e.short_name = C.strdup(short_name)
    }
    else { // 3
    e.short_name = (voidptr(0))
}
    e.flags = flags
}

fn namelist_free(lp &Namelist_t)  {
    for lp.count > 0 {
        e := &lp.array [lp.count --$]
        C.free(e.name)
        C.free(e.short_name)
    }
    C.free(lp.array)
    lp.array = (voidptr(0))
    lp.size = 0
}

fn namelist_find(lp &Namelist_t, name &i8) &Namelist_entry_t {
    i := 0
    for i = 0 ; i < lp.count ; i ++ {
        e := &lp.array [i]
        if !C.strcmp(e.name, name) {
        return e
        }
    }
    return (voidptr(0))
}

fn get_c_name(buf &i8, buf_size usize, file &i8)  {
    p := &i8(0)
    r := &i8(0)

    len := usize(0)
    i := usize(0)

    c := 0
    q := &i8(0)
    p = C.strrchr(file, `/`)
    if !p {
    p = file
    }
    else { // 3
    p ++
}
    r = C.strrchr(p, `.`)
    if !r {
    len = C.strlen(p)
    }
    else { // 3
    len = r - p
}
    C.pstrcpy(buf, buf_size, c_ident_prefix)
    q = buf + C.strlen(buf)
    for i = 0 ; i < len ; i ++ {
        c = p [i]
        if !((c >= `0` && c <= `9`) || (c >= `A` && c <= `Z`) || (c >= `a` && c <= `z`)) {
            c = `_`
        }
        if (q - buf) < buf_size - 1 {
        *q ++ = c
        }
    }
    *q = ``
}

fn dump_hex(f &C.FILE, buf &u8, len usize)  {
    i := usize(0)
    col := usize(0)

    col = 0
    for i = 0 ; i < len ; i ++ {
        C.fprintf(f, c' 0x%02x,', buf [i] )
        if col ++$ == 8 {
            C.fprintf(f, c'\n')
            col = 0
        }
    }
    if col != 0 {
    C.fprintf(f, c'\n')
    }
}

fn output_object_code(ctx &JSContext, fo &C.FILE, obj JSValue, c_name &i8, load_only BOOL)  {
    out_buf := &u8(0)
    out_buf_len := usize(0)
    flags := 0
    flags = (1 << 0)
    if byte_swap {
    flags |= (1 << 1)
    }
    out_buf = js_writeobject(ctx, &out_buf_len, obj, flags)
    if !out_buf {
        js_std_dump_error(ctx)
        C.exit(1)
    }
    namelist_add(&cname_list, c_name, (voidptr(0)), load_only)
    C.fprintf(fo, c'const uint32_t %s_size = %u;\n\n', c_name, u32(out_buf_len))
    C.fprintf(fo, c'const uint8_t %s[%u] = {\n', c_name, u32(out_buf_len))
    dump_hex(fo, out_buf, out_buf_len)
    C.fprintf(fo, c'};\n\n')
    js_free(ctx, out_buf)
}

fn js_module_dummy_init(ctx &JSContext, m &JSModuleDef) int {
    abort()
}

fn find_unique_cname(cname &i8, cname_size usize)  {
    cname1 := [1024]i8{}
    suffix_num := 0
    len := usize(0)
    max_len := usize(0)

    (void(0))
    len = C.strlen(cname)
    max_len = cname_size - 16
    if len > max_len {
    cname [max_len]  = ``
    }
    suffix_num = 1
    for  ;  ;  {
        __builtin___snprintf_chk(cname1, sizeof(cname1), 0, __builtin_object_size(cname1, if 2 > 1{ 1 } else {0}), c'%s_%d', cname, suffix_num)
        if !namelist_find(&cname_list, cname1) {
        break

        }
        suffix_num ++
    }
    pstrcpy(cname, cname_size, cname1)
}

fn jsc_module_loader(ctx &JSContext, module_name &i8, opaque voidptr) &JSModuleDef {
    m := &JSModuleDef(0)
    e := &Namelist_entry_t(0)
    e = namelist_find(&cmodule_list, module_name)
    if e {
        namelist_add(&init_module_list, e.name, e.short_name, 0)
        m = js_newcmodule(ctx, module_name, js_module_dummy_init)
    }
    else if has_suffix(module_name, c'.so') {
        C.fprintf(C.__stderrp, c"Warning: binary module '%s' will be dynamically loaded\n", module_name)
        m = js_newcmodule(ctx, module_name, js_module_dummy_init)
        dynamic_export = const_true
    }
    else {
        buf_len := usize(0)
        buf := &u8(0)
        func_val := JSValue{}
        cname := [1024]i8{}
        buf = js_load_file(ctx, &buf_len, module_name)
        if !buf {
            js_throwreferenceerror(ctx, c"could not load module filename '%s'", module_name)
            return (voidptr(0))
        }
        func_val = js_eval(ctx, &i8(buf), buf_len, module_name, (1 << 0) | (1 << 5))
        js_free(ctx, buf)
        if js_isexception(func_val) {
        return (voidptr(0))
        }
        get_c_name(cname, sizeof(cname), module_name)
        if namelist_find(&cname_list, cname) {
            find_unique_cname(cname, sizeof(cname))
        }
        output_object_code(ctx, outfile, func_val, cname, true)
        m = ((func_val).u.ptr)
        js_freevalue(ctx, func_val)
    }
    return m
}

fn compile_file(ctx &JSContext, fo &C.FILE, filename &i8, c_name1 &i8, module_ int)  {
    buf := &u8(0)
    c_name := [1024]i8{}
    eval_flags := 0
    obj := JSValue{}
    buf_len := usize(0)
    buf = js_load_file(ctx, &buf_len, filename)
    if !buf {
        C.fprintf(C.__stderrp, c"Could not load '%s'\n", filename)
        C.exit(1)
    }
    eval_flags = (1 << 5)
    if module_ < 0 {
        module_ = (has_suffix(filename, c'.mjs') || js_detectmodule(&i8(buf), buf_len))
    }
    if module_ {
    eval_flags |= (1 << 0)
    }
    else { // 3
    eval_flags |= (0 << 0)
}
    obj = js_eval(ctx, &i8(buf), buf_len, filename, eval_flags)
    if js_isexception(obj) {
        js_std_dump_error(ctx)
        C.exit(1)
    }
    js_free(ctx, buf)
    if c_name1 {
        pstrcpy(c_name, sizeof(c_name), c_name1)
    }
    else {
        get_c_name(c_name, sizeof(c_name), filename)
    }
    output_object_code(ctx, fo, obj, c_name, const_false)
    js_freevalue(ctx, obj)
}

[export:'main_c_template1']
const (
main_c_template1   = c'int main(int argc, char **argv)\n{\n  JSRuntime *rt;\n  JSContext *ctx;\n  rt = JS_NewRuntime();\n  js_std_set_worker_new_context_func(JS_NewCustomContext);\n  js_std_init_handlers(rt);\n'
)

[export:'main_c_template2']
const (
main_c_template2   = c'  js_std_loop(ctx);\n  JS_FreeContext(ctx);\n  JS_FreeRuntime(rt);\n  return 0;\n}\n'
)

fn help()  {
    C.printf(c"QuickJS Compiler version 2021-03-27\nusage: qjsc [options] [files]\n\noptions are:\n-c          only output bytecode in a C file\n-e          output main() and bytecode in a C file (default = executable output)\n-o output   set the output filename\n-N cname    set the C name of the generated data\n-m          compile as Javascript module (default=autodetect)\n-D module_name         compile a dynamically loaded module or worker\n-M module_name[,cname] add initialization code for an external C module\n-x          byte swapped output\n-p prefix   set the prefix of the generated C names\n-S n        set the maximum stack size to 'n' bytes (default=%d)\n", (256 * 1024))
    C.exit(1)
}

fn output_executable(out_filename &i8, cfilename &i8, use_lto BOOL, verbose BOOL, exename &i8) int {
    C.fprintf(C.__stderrp, c'Executable output is not supported for this target\n')
    C.exit(1)
    return 0
}

enum OutputTypeEnum {
    output_c
    output_c_main
    output_executable
}

fn main()  {
    c := 0
    i := 0
    verbose := 0

    out_filename := &i8(0)
    cname := &i8(0)

    cfilename := [1024]i8{}
    fo := &C.FILE(0)
    rt := &JSRuntime(0)
    ctx := &JSContext(0)
    use_lto := BOOL{}
    module_ := 0
    output_type := OutputTypeEnum{}
    stack_size := usize(0)
    dynamic_module_list := Namelist_t{}
    out_filename = (voidptr(0))
    output_type = OutputTypeEnum.output_executable
    cname = (voidptr(0))
    feature_bitmap = (-1)
    module_ = -1
    byte_swap = const_false
    verbose = 0
    use_lto = const_false
    stack_size = 0
    C.memset(&dynamic_module_list, 0, sizeof(dynamic_module_list))
    namelist_add(&cmodule_list, c'std', c'std', 0)
    namelist_add(&cmodule_list, c'os', c'os', 0)
    for  ;  ;  {
        c = getopt(argc, os.argv, c'ho:cN:f:mxevM:p:S:D:')
        if c == -1 {
        break

        }
        match c {
         `h`// case comp body kind=CallExpr is_enum=false
        {
        help()
         }
        `o`// case comp body kind=BinaryOperator is_enum=false
        {
        out_filename = optarg
         }
        `c`// case comp body kind=BinaryOperator is_enum=false
        {
        output_type = OutputTypeEnum.output_c
         }
        `e`// case comp body kind=BinaryOperator is_enum=false
        {
        output_type = OutputTypeEnum.output_c_main
         }
        `N`// case comp body kind=BinaryOperator is_enum=false
        {
        cname = optarg
         }
        `f`// case comp stmt
            p := &i8(0)
            p = optarg
            if !C.strcmp(optarg, c'lto') {
                use_lto = const_true
            }
            else if strstart(p, c'no-', &p) {
                use_lto = const_true
                for i = 0 ; i < (sizeof(feature_list) / sizeof((feature_list) [0] )) ; i ++ {
                    if !C.strcmp(p, feature_list [i] .option_name) {
                        feature_bitmap &= ~(u64(1) << i)

                    }
                }
                if i == (sizeof(feature_list) / sizeof((feature_list) [0] )) {
                goto bad_feature /* id: 0x1429ba748 */
                }
            }
            else {
                /*RRRREG bad_feature id=0x1429ba748 */
                bad_feature:
                C.fprintf(C.__stderrp, c'unsupported feature: %s\n', optarg)
                C.exit(1)
            }
        }
         }
        `m`// case comp body kind=BinaryOperator is_enum=false
        {
        module_ = 1
         }
        `M`// case comp stmt
            p := &i8(0)
            path := [1024]i8{}
            cname := [1024]i8{}
            pstrcpy(path, sizeof(path), optarg)
            p = C.strchr(path, `,`)
            if p {
                *p = ``
                pstrcpy(cname, sizeof(cname), p + 1)
            }
            else {
                get_c_name(cname, sizeof(cname), path)
            }
            namelist_add(&cmodule_list, path, cname, 0)
        }
         }
        `D`// case comp body kind=CallExpr is_enum=false
        {
        namelist_add(&dynamic_module_list, optarg, (voidptr(0)), 0)
         }
        `x`// case comp body kind=BinaryOperator is_enum=false
        {
        byte_swap = const_true
         }
        `v`// case comp body kind=UnaryOperator is_enum=false
        {
        verbose ++
         }
        `p`// case comp body kind=BinaryOperator is_enum=false
        {
        c_ident_prefix = optarg
         }
        `S`// case comp body kind=BinaryOperator is_enum=false
        {
        stack_size = usize(strtod(optarg, (voidptr(0))))
        }
         else {

        }
        }
    }
    if optind >= argc {
    help()
    }
    if !out_filename {
        if output_type == OutputTypeEnum.output_executable {
            out_filename = c'a.out'
        }
        else {
            out_filename = c'out.c'
        }
    }
    if output_type == OutputTypeEnum.output_executable {
        __builtin___snprintf_chk(cfilename, sizeof(cfilename), 0, __builtin_object_size(cfilename, if 2 > 1{ 1 } else {0}), c'/tmp/out%d.c', getpid())
    }
    else {
        pstrcpy(cfilename, sizeof(cfilename), out_filename)
    }
    fo = C.fopen(cfilename, c'w')
    if !fo {
        C.perror(cfilename)
        C.exit(1)
    }
    outfile = fo
    rt = js_newruntime()
    ctx = js_newcontext(rt)
    js_setmoduleloaderfunc(rt, (voidptr(0)), jsc_module_loader, (voidptr(0)))
    C.fprintf(fo, c'/* File generated automatically by the QuickJS compiler. */\n\n')
    if output_type != OutputTypeEnum.output_c {
        C.fprintf(fo, c'#include \"quickjs-libc.h\"\n\n')
    }
    else {
        C.fprintf(fo, c'#include <inttypes.h>\n\n')
    }
    for i = optind ; i < argc ; i ++ {
        filename := os.argv [i]
        compile_file(ctx, fo, filename, cname, module_)
        cname = (voidptr(0))
    }
    for i = 0 ; i < dynamic_module_list.count ; i ++ {
        if !jsc_module_loader(ctx, dynamic_module_list.array [i] .name, (voidptr(0))) {
            C.fprintf(C.__stderrp, c"Could not load dynamic module '%s'\n", dynamic_module_list.array [i] .name)
            C.exit(1)
        }
    }
    if output_type != OutputTypeEnum.output_c {
        C.fprintf(fo, c'static JSContext *JS_NewCustomContext(JSRuntime *rt)\n{\n  JSContext *ctx = JS_NewContextRaw(rt);\n  if (!ctx)\n    return NULL;\n')
        C.fprintf(fo, c'  JS_AddIntrinsicBaseObjects(ctx);\n')
        for i = 0 ; i < (sizeof(feature_list) / sizeof((feature_list) [0] )) ; i ++ {
            if (feature_bitmap & (u64(1) << i)) && feature_list [i] .init_name {
                C.fprintf(fo, c'  JS_AddIntrinsic%s(ctx);\n', feature_list [i] .init_name)
            }
        }
        for i = 0 ; i < init_module_list.count ; i ++ {
            e := &init_module_list.array [i]
            C.fprintf(fo, c'  {\n    extern JSModuleDef *js_init_module_%s(JSContext *ctx, const char *name);\n    js_init_module_%s(ctx, \"%s\");\n  }\n', e.short_name, e.short_name, e.name)
        }
        for i = 0 ; i < cname_list.count ; i ++ {
            e := &cname_list.array [i]
            if e.flags {
                C.fprintf(fo, c'  js_std_eval_binary(ctx, %s, %s_size, 1);\n', e.name, e.name)
            }
        }
        C.fprintf(fo, c'  return ctx;\n}\n\n')
        C.fputs(main_c_template1, fo)
        if stack_size != 0 {
            C.fprintf(fo, c'  JS_SetMaxStackSize(rt, %u);\n', u32(stack_size))
        }
        if feature_bitmap & (1 << 9) {
            C.fprintf(fo, c'  JS_SetModuleLoaderFunc(rt, NULL, js_module_loader, NULL);\n')
        }
        C.fprintf(fo, c'  ctx = JS_NewCustomContext(rt);\n  js_std_add_helpers(ctx, argc, argv);\n')
        for i = 0 ; i < cname_list.count ; i ++ {
            e := &cname_list.array [i]
            if !e.flags {
                C.fprintf(fo, c'  js_std_eval_binary(ctx, %s, %s_size, 0);\n', e.name, e.name)
            }
        }
        C.fputs(main_c_template2, fo)
    }
    js_freecontext(ctx)
    js_freeruntime(rt)
    C.fclose(fo)
    if output_type == OutputTypeEnum.output_executable {
        return
    }
    namelist_free(&cname_list)
    namelist_free(&cmodule_list)
    namelist_free(&init_module_list)
    return
}