memory_size :: () -> i32 #intrinsic ---
memory_grow :: (val: i32) -> i32 #intrinsic ---
+memory_copy :: (dst: rawptr, src: rawptr, count: i32) -> void #intrinsic ---
+memory_fill :: (dst: rawptr, byte: u8, count: i32) -> void #intrinsic ---
clz_i32 :: (val: i32) -> i32 #intrinsic ---
ctz_i32 :: (val: i32) -> i32 #intrinsic ---
// However, it might be worth switching to an intrinsic completely
// and having the intrinsic know whether or not to output the instruction
// or an inlined version of this procedure.
-copy :: (dst_: rawptr, src_: rawptr, len: u32) {
+use package core.intrinsics.wasm { memory_copy, memory_fill }
+
+// Even though I thought this would work, this method of aliases functions
+// does not currently work. There needs to be a second level of indirection
+// on entities to allow for this case to work, which may not be hard to change
+// but still needs to happen.
+// copy :: memory_copy
+// set :: memory_fill
+
+copy :: (dest: rawptr, src: rawptr, count: i32) do memory_copy(dest, src, count);
+set :: (dest: rawptr, byte: u8, count: i32) do memory_fill(dest, byte, count);
+
+// Old and slow copy and set
+copy_ :: (dst_: rawptr, src_: rawptr, len: u32) {
dst := cast(^u8) dst_;
src := cast(^u8) src_;
for i: 0 .. len do dst[i] = src[i];
}
-// The same thing goes for this procedure too.
-set :: (start: rawptr, length: u32, value: u8) {
+set_ :: (start: rawptr, value: u8, length: u32) {
s := cast(^u8) start;
for i: 0 .. length do s[i] = value;
}
ONYX_INTRINSIC_UNDEFINED,
ONYX_INTRINSIC_MEMORY_SIZE, ONYX_INTRINSIC_MEMORY_GROW,
+ ONYX_INTRINSIC_MEMORY_COPY, ONYX_INTRINSIC_MEMORY_FILL,
ONYX_INTRINSIC_I32_CLZ, ONYX_INTRINSIC_I32_CTZ, ONYX_INTRINSIC_I32_POPCNT,
ONYX_INTRINSIC_I32_AND, ONYX_INTRINSIC_I32_OR, ONYX_INTRINSIC_I32_XOR,
} WasmFuncType;
#define SIMD_INSTR_MASK 0x10000
+#define EXT_INSTR_MASK 0x20000
typedef enum WasmInstructionType {
WI_UNREACHABLE = 0x00,
WI_I32X4_TRUNC_SAT_F32X4_U = SIMD_INSTR_MASK | 249,
WI_F32X4_CONVERT_I32X4_S = SIMD_INSTR_MASK | 250,
WI_F32X4_CONVERT_I32X4_U = SIMD_INSTR_MASK | 251,
+
+
+ WI_MEMORY_COPY = EXT_INSTR_MASK | 0x0a,
+ WI_MEMORY_FILL = EXT_INSTR_MASK | 0x0b,
} WasmInstructionType;
typedef union {
static IntrinsicMap builtin_intrinsics[] = {
{ "memory_size", ONYX_INTRINSIC_MEMORY_SIZE },
{ "memory_grow", ONYX_INTRINSIC_MEMORY_GROW },
+ { "memory_copy", ONYX_INTRINSIC_MEMORY_COPY },
+ { "memory_fill", ONYX_INTRINSIC_MEMORY_FILL },
{ "clz_i32", ONYX_INTRINSIC_I32_CLZ },
{ "ctz_i32", ONYX_INTRINSIC_I32_CTZ },
case Token_Type_Right_Arrow: {
AstBinaryOp* method_call = make_node(AstBinaryOp, Ast_Kind_Method_Call);
- method_call->token = expect_token(parser, Token_Type_Right_Arrow);
+ method_call->token = expect_token(parser, Token_Type_Right_Arrow);
method_call->left = retval;
method_call->right = parse_factor(parser);
AstIfWhile* root_if = if_node;
// CLEANUP: All of the control blocks use this same kind of logic, and it
- // is underpowered for what I think should be possible. Factor it out and
+ // is underpowered for what I think should be possible. Factor it out and
// make it better?
if (peek_token(1)->type == ':') {
OnyxToken* local_sym = expect_token(parser, Token_Type_Symbol);
retval = parse_jump_stmt(parser, Token_Type_Keyword_Break, Jump_Type_Break);
break;
- case Token_Type_Keyword_Continue:
+ case Token_Type_Keyword_Continue:
retval = parse_jump_stmt(parser, Token_Type_Keyword_Continue, Jump_Type_Continue);
break;
bh_arr_push(poly_params, ((AstPolyStructParam) {
.token = sym_token,
.type_node = param_type,
- .type = NULL,
+ .type = NULL,
}));
if (parser->curr->type != ')')
}
bh_arr_each(OnyxToken *, member_name, member_list_temp) {
- AstStructMember* mem = make_node(AstStructMember, Ast_Kind_Struct_Member);
+ AstStructMember* mem = make_node(AstStructMember, Ast_Kind_Struct_Member);
mem->token = *member_name;
mem->type_node = member_type;
mem->initial_value = initial_value;
curr_param.default_value = parse_expression(parser, 0);
if (param_is_baked) {
- param_is_baked = 0;
+ param_is_baked = 0;
bh_arr(AstPolyParam) pv = *parser->polymorph_context.poly_params;
bh_arr_push(pv, ((AstPolyParam) {
// HACK: This should maybe be entered elsewhere?
ENTITY_SUBMIT(node);
}
-
+
AstBinding* binding = make_node(AstBinding, Ast_Kind_Binding);
binding->token = symbol;
binding->node = (AstNode *) node;
if (res == NULL) return NULL;
- if (res->kind == Ast_Kind_Symbol) {
- return symbol_resolve(start_scope, res->token);
- }
-
return res;
}
switch (call->intrinsic) {
case ONYX_INTRINSIC_MEMORY_SIZE: WID(WI_MEMORY_SIZE, 0x00); break;
case ONYX_INTRINSIC_MEMORY_GROW: WID(WI_MEMORY_GROW, 0x00); break;
+ case ONYX_INTRINSIC_MEMORY_COPY: WIL(WI_MEMORY_COPY, 0x00); break;
+ case ONYX_INTRINSIC_MEMORY_FILL: WID(WI_MEMORY_FILL, 0x00); break;
case ONYX_INTRINSIC_I32_CLZ: WI(WI_I32_CLZ); break;
case ONYX_INTRINSIC_I32_CTZ: WI(WI_I32_CTZ); break;
bh_buffer_write_byte(buff, 0xFD);
leb = uint_to_uleb128((u64) (instr->type &~ SIMD_INSTR_MASK), &leb_len);
bh_buffer_append(buff, leb, leb_len);
+
+ } else if (instr->type & EXT_INSTR_MASK) {
+ bh_buffer_write_byte(buff, 0xFC);
+ leb = uint_to_uleb128((u64) (instr->type &~ EXT_INSTR_MASK), &leb_len);
+ bh_buffer_append(buff, leb, leb_len);
} else {
bh_buffer_write_byte(buff, (u8) instr->type);
case WI_IF_START:
case WI_MEMORY_SIZE:
case WI_MEMORY_GROW:
+ case WI_MEMORY_FILL:
leb = uint_to_uleb128((u64) instr->data.i1, &leb_len);
bh_buffer_append(buff, leb, leb_len);
break;
+
+ case WI_MEMORY_COPY:
+ leb = uint_to_uleb128((u64) instr->data.i1, &leb_len);
+ bh_buffer_append(buff, leb, leb_len);
+
+ leb = uint_to_uleb128((u64) instr->data.i2, &leb_len);
+ bh_buffer_append(buff, leb, leb_len);
+ break;
case WI_JUMP_TABLE: {
BranchTable* bt = (BranchTable *) instr->data.p;
mem_size := sizeof bool * input.count * input.count * max_terminal;
T := cast(^bool) calloc(mem_size);
defer cfree(T);
- memory.set(T, mem_size, ~~false);
+ memory.set(T, ~~false, mem_size);
for s: 0 .. input.count {
for ^term: terminate_rules {
printf("Corner product: %l\n", prod);
grid : [12 * 12] u32;
- memory.set(^grid, sizeof [12 * 12] u32, 0);
+ memory.set(^grid, 0, sizeof [12 * 12] u32);
to_process : [..] tile_pos_state;
array.init(^to_process);