break;
case Ast_Kind_Function:
- // NOTE: Will need something like this at some point
- // AstFunction* func = (AstFunction *) expr;
- // bh_arr_each(AstParam, param, func->params) {
- // if (param->default_value != NULL) {
- // onyx_message_add(Msg_Type_Literal,
- // func->token->pos,
- // "cannot use functions with default parameters in this way");
- // retval = 1;
- // break;
- // }
- // }
if (expr->type == NULL)
YIELD(expr->token->pos, "Waiting for function type to be resolved.");
case Type_Kind_Basic: return type->Basic.size;
case Type_Kind_MultiPointer:
case Type_Kind_Pointer: return POINTER_SIZE;
- case Type_Kind_Function: return 4;
+ case Type_Kind_Function: return 2 * POINTER_SIZE;
case Type_Kind_Array: return type->Array.size;
case Type_Kind_Struct: return type->Struct.size;
case Type_Kind_Enum: return type_size_of(type->Enum.backing);
case Type_Kind_Slice: return POINTER_SIZE * 2; // HACK: These should not have to be 16 bytes in size, they should only have to be 12,
case Type_Kind_VarArgs: return POINTER_SIZE * 2; // but there are alignment issues right now with that so I decided to not fight it and just make them 16 bytes in size.
- case Type_Kind_DynArray: return POINTER_SIZE + 8 + 2 * POINTER_SIZE; // data (8), count (4), capacity (4), allocator { func (4), ---(4), data (8) }
+ case Type_Kind_DynArray: return POINTER_SIZE + 8 + 4 * POINTER_SIZE; // data (8), count (4), capacity (4), allocator { func (8), data (8) }
case Type_Kind_Compound: return type->Compound.size;
case Type_Kind_Distinct: return type_size_of(type->Distinct.base_type);
default: return 0;
case Type_Kind_Basic: return type->Basic.alignment;
case Type_Kind_MultiPointer:
case Type_Kind_Pointer: return POINTER_SIZE;
- case Type_Kind_Function: return 4;
+ case Type_Kind_Function: return POINTER_SIZE;
case Type_Kind_Array: return type_alignment_of(type->Array.elem);
case Type_Kind_Struct: return type->Struct.alignment;
case Type_Kind_Enum: return type_alignment_of(type->Enum.backing);
elem_offset += bh_max(type_size_of(type->Compound.types[i]), 4);
}
- } else if (type->kind == Type_Kind_Slice || type->kind == Type_Kind_VarArgs) {
+ } else if (type->kind == Type_Kind_Slice || type->kind == Type_Kind_VarArgs || type->kind == Type_Kind_Function) {
u32 mem_count = type_structlike_mem_count(type);
StructMember smem = { 0 };
fori (i, 0, mem_count) {
{ POINTER_SIZE, 1, &basic_types[Basic_Kind_U32], "length", NULL, NULL, -1, 0, 0 },
};
+static const StructMember func_members[] = {
+ { 0, 0, &basic_types[Basic_Kind_U32], "__funcidx", NULL, NULL, -1, 0, 0 },
+ { POINTER_SIZE, 1, &basic_types[Basic_Kind_Rawptr], "data", NULL, NULL, -1, 0, 0 },
+};
+
b32 type_lookup_member(Type* type, char* member, StructMember* smem) {
if (type->kind == Type_Kind_Pointer) type = type->Pointer.elem;
return 0;
}
+ case Type_Kind_Function: {
+ fori (i, 0, (i64) (sizeof(func_members) / sizeof(StructMember))) {
+ if (strcmp(func_members[i].name, member) == 0) {
+ *smem = func_members[i];
+ return 1;
+ }
+ }
+ }
+
default: return 0;
}
}
return 1;
}
+ case Type_Kind_Function: {
+ if (idx > 2) return 0;
+
+ *smem = func_members[idx];
+ return 1;
+ }
+
default: return 0;
}
}
switch (type->kind) {
case Type_Kind_Slice:
case Type_Kind_VarArgs: return 2;
+ case Type_Kind_Function: return 2;
case Type_Kind_Compound: return bh_arr_length(type->Compound.linear_members);
default: return 1;
}
two->offset = 0;
return 1;
+ case Type_Kind_Function:
+ if (idx == 0) {
+ two->type = &basic_types[Basic_Kind_U32];
+ two->offset = 0;
+ }
+ if (idx == 1) {
+ two->type = &basic_types[Basic_Kind_Rawptr];
+ two->offset = POINTER_SIZE;
+ }
+ return 1;
+
default: {
if (idx > 0) return 0;
two->offset = 0;
return -1;
}
+ case Type_Kind_Function: {
+ if (offset == 0) return 0;
+ if (offset == POINTER_SIZE) return 1;
+ return -1;
+ }
default:
if (offset == 0) return 0;
return -1;
b32 type_results_in_void(Type* type) {
return (type == NULL)
- || (type->kind == Type_Kind_Basic && type->Basic.kind == Basic_Kind_Void)
- || ( (type->kind == Type_Kind_Function)
- && (type->Function.return_type->kind == Type_Kind_Basic)
- && (type->Function.return_type->Basic.kind == Basic_Kind_Void));
+ || (type->kind == Type_Kind_Basic && type->Basic.kind == Basic_Kind_Void);
+ // || ( (type->kind == Type_Kind_Function)
+ // && (type->Function.return_type->kind == Type_Kind_Basic)
+ // && (type->Function.return_type->Basic.kind == Basic_Kind_Void));
}
b32 type_is_array_accessible(Type* type) {
if (type->kind == Type_Kind_Array) return 1;
if (type->kind == Type_Kind_Struct) return 1;
if (type->kind == Type_Kind_Slice) return 1;
+ if (type->kind == Type_Kind_Function) return 1;
if (type->kind == Type_Kind_DynArray) return 1;
if (type->kind == Type_Kind_VarArgs) return 1;
if (type->kind == Type_Kind_Pointer) {
if (type->kind == Type_Kind_Struct) return 1;
if (type->kind == Type_Kind_Slice) return 1;
if (type->kind == Type_Kind_DynArray) return 1;
+ if (type->kind == Type_Kind_Function) return 1;
if (type->kind == Type_Kind_VarArgs) return 1;
return 0;
}
case Type_Kind_Struct: return type->Struct.mem_count;
case Type_Kind_Slice: return 2;
case Type_Kind_VarArgs: return 2;
+ case Type_Kind_Function: return 2;
case Type_Kind_DynArray: return 4;
default: return 0;
}
switch (type->kind) {
case Type_Kind_Slice: return 1;
case Type_Kind_VarArgs: return 1;
+ case Type_Kind_Function: return 1;
case Type_Kind_DynArray: return 0;
case Type_Kind_Struct: return 0;
default: return 0;
if (type->kind == Type_Kind_Distinct) return onyx_type_to_wasm_type(type->Distinct.base_type);
if (type->kind == Type_Kind_Pointer) return WASM_TYPE_PTR;
if (type->kind == Type_Kind_Array) return WASM_TYPE_PTR;
- if (type->kind == Type_Kind_Function) return WASM_TYPE_FUNC;
+ if (type->kind == Type_Kind_Function) return WASM_TYPE_VOID;
if (type->kind == Type_Kind_MultiPointer) return WASM_TYPE_PTR;
if (type->kind == Type_Kind_Basic) {
if (type->kind == Type_Kind_Struct) type = type_struct_is_just_one_basic_value(type);
if (type->kind == Type_Kind_Enum) type = type->Enum.backing;
if (type->kind == Type_Kind_Distinct) type = type->Distinct.base_type;
- if (type->kind == Type_Kind_Function) type = &basic_types[Basic_Kind_U32];
+ if (type->kind == Type_Kind_Function) assert(5678 && 0);
assert(type);
if (type->kind == Type_Kind_Struct) type = type_struct_is_just_one_basic_value(type);
if (type->kind == Type_Kind_Enum) type = type->Enum.backing;
if (type->kind == Type_Kind_Distinct) type = type->Distinct.base_type;
- if (type->kind == Type_Kind_Function) type = &basic_types[Basic_Kind_U32];
+ if (type->kind == Type_Kind_Function) assert(1234 && 0);
assert(type);
u64 iterator_close_func = local_raw_allocate(mod->local_alloc, WASM_TYPE_FUNC);
u64 iterator_remove_func = local_raw_allocate(mod->local_alloc, WASM_TYPE_FUNC);
u64 iterator_done_bool = local_raw_allocate(mod->local_alloc, WASM_TYPE_INT32);
+ WI(for_node->token, WI_DROP);
WIL(for_node->token, WI_LOCAL_SET, iterator_remove_func);
+ WI(for_node->token, WI_DROP);
WIL(for_node->token, WI_LOCAL_SET, iterator_close_func);
+ WI(for_node->token, WI_DROP);
WIL(for_node->token, WI_LOCAL_SET, iterator_next_func);
WIL(for_node->token, WI_LOCAL_SET, iterator_data_ptr);
}
emit_expression(mod, &code, binop->left);
+ if (binop->left->type->kind == Type_Kind_Function) { // nocheckin
+ WI(NULL, WI_DROP);
+ }
+
emit_expression(mod, &code, binop->right);
+ if (binop->right->type->kind == Type_Kind_Function) { // nocheckin
+ WI(NULL, WI_DROP);
+ }
WI(binop->token, binop_instr);
} else {
emit_expression(mod, &code, call->callee);
+ WI(NULL, WI_DROP);
i32 type_idx = generate_type_idx(mod, call->callee->type);
WID(NULL, WI_CALL_INDIRECT, ((WasmInstructionData) { type_idx, 0x00 }));
i32 elemidx = get_element_idx(mod, (AstFunction *) expr);
WID(NULL, WI_I32_CONST, elemidx);
+ WIL(NULL, WI_I32_CONST, 0);
break;
}
break;
}
+ case Ast_Kind_Capture_Local: {
+ printf("HANDLE CAPTURE LOCAL!!!\n");
+ assert(0);
+ break;
+ }
+
default:
bh_printf("Unhandled case: %d\n", expr->kind);
DEBUG_HERE;
} else if (type->kind == Type_Kind_Function) {
WID(NULL, WI_I32_CONST, mod->null_proc_func_idx);
+ WIL(NULL, WI_I32_CONST, 0);
} else {
if (type == &basic_types[Basic_Kind_Void]) {
// continue;
// }
+ if (type->kind == Type_Kind_Function) {
+ output_unsigned_integer(6, §ion_buff);
+ output_unsigned_integer(type->Function.param_count, §ion_buff);
+
+ fori (i, 0, (i32) type->Function.param_count) {
+ output_unsigned_integer(type->Function.params[i]->id, §ion_buff);
+ }
+
+ output_unsigned_integer(type->Function.return_type->id, §ion_buff);
+ continue;
+ }
+
if (type_is_structlike_strict(type)) {
output_unsigned_integer(3, §ion_buff);
continue;
}
- if (type->kind == Type_Kind_Function) {
- output_unsigned_integer(6, §ion_buff);
- output_unsigned_integer(type->Function.param_count, §ion_buff);
-
- fori (i, 0, (i32) type->Function.param_count) {
- output_unsigned_integer(type->Function.params[i]->id, §ion_buff);
- }
-
- output_unsigned_integer(type->Function.return_type->id, §ion_buff);
- continue;
- }
-
if (type->kind == Type_Kind_Distinct) {
output_unsigned_integer(5, §ion_buff);
output_unsigned_integer(2, §ion_buff);
use wasi
use runtime
-use core
use wasi {
IOVec, SubscriptionTagged, Subscription, Event, Size,
poll_oneoff, fd_write, fd_datasync, fd_read,
__runtime_initialize,
Multi_Threading_Enabled,
}
+use core {
+ __flush_stdio
+}
// Platform supports
package runtime.platform
use runtime
-use core
+use core {package, *}
use wasi
-use core
-
#if runtime.runtime != .Wasi {
#error "The file system library is currently only available on the WASI runtime, and should only be included if that is the chosen runtime."
}
err := wasi.fd_readdir(dir.dir_fd, ~~buffer, 512, dir.last_cookie, &bufused);
if err != .Success || bufused == 0 do return false;
- dirent := cast(&wasi.DirEnt) buffer;
+ dirent := cast(& wasi.DirEnt) buffer;
switch dirent.d_type {
case .Unknown do out_entry.type = .Unknown;
case .BlockDevice do out_entry.type = .Block;
out_entry.identifier = ~~dirent.d_ino;
out_entry.name_length = dirent.d_namlen;
memory.set(~~&out_entry.name_data, 0, 256);
- memory.copy(~~&out_entry.name_data, ~~(dirent + 1), math.min(dirent.d_namlen, sizeof typeof out_entry.name_data));
+ memory.copy(~~&out_entry.name_data, ~~(cast([&] wasi.DirEnt) dirent + 1), math.min(dirent.d_namlen, sizeof typeof out_entry.name_data));
dir.last_cookie = dirent.d_next;
return true;
i32 tls_base;
i32 stack_base;
i32 funcidx;
+ i32 closureptr;
i32 dataptr;
wasm_instance_t* instance;
i32 thread_id = thread->id;
{ // Call the _thread_start procedure
- wasm_val_t args[] = { WASM_I32_VAL(thread_id), WASM_I32_VAL(thread->tls_base), WASM_I32_VAL(thread->stack_base), WASM_I32_VAL(thread->funcidx), WASM_I32_VAL(thread->dataptr) };
+ wasm_val_t args[] = { WASM_I32_VAL(thread_id), WASM_I32_VAL(thread->tls_base), WASM_I32_VAL(thread->stack_base), WASM_I32_VAL(thread->funcidx), WASM_I32_VAL(thread->closureptr), WASM_I32_VAL(thread->dataptr) };
wasm_val_vec_t results = { 0, 0 };
wasm_val_vec_t args_array = WASM_ARRAY_VEC(args);
return 0;
}
-ONYX_DEF(__spawn_thread, (WASM_I32, WASM_I32, WASM_I32, WASM_I32, WASM_I32), (WASM_I32)) {
+ONYX_DEF(__spawn_thread, (WASM_I32, WASM_I32, WASM_I32, WASM_I32, WASM_I32, WASM_I32), (WASM_I32)) {
if (threads == NULL) bh_arr_new(bh_heap_allocator(), threads, 128);
bh_arr_insert_end(threads, 1);
OnyxThread *thread = &bh_arr_last(threads);
thread->tls_base = params->data[1].of.i32;
thread->stack_base = params->data[2].of.i32;
thread->funcidx = params->data[3].of.i32;
- thread->dataptr = params->data[4].of.i32;
+ thread->closureptr = params->data[4].of.i32;
+ thread->dataptr = params->data[5].of.i32;
#ifdef _BH_LINUX
pthread_create(&thread->thread, NULL, onyx_run_thread, thread);
a_newline := '\n';
printf("{}", a_newline);
println("Something else");
-}
\ No newline at end of file
+}