Skip to content

Commit 1921d42

Browse files
committed
Sync source
1 parent ca55a62 commit 1921d42

File tree

5 files changed

+181
-99
lines changed

5 files changed

+181
-99
lines changed

examples/Wasm_Blink/Wasm_Blink.ino

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -125,11 +125,10 @@ m3ApiRawFunction(m3_arduino_getPinLED)
125125

126126
m3ApiRawFunction(m3_arduino_print)
127127
{
128-
m3ApiGetArgMem(const char *, buff)
129-
130-
//printf("api: print %p\n", out);
131-
Serial.print(buff);
128+
m3ApiGetArgMem (const uint8_t *, buf)
129+
m3ApiGetArg (uint32_t, len)
132130

131+
Serial.write(buf, len);
133132
m3ApiSuccess();
134133
}
135134

@@ -148,9 +147,9 @@ M3Result LinkArduino (IM3Runtime runtime)
148147
m3_LinkRawFunction (module, arduino, "pinMode", "v(ii)", &m3_arduino_pinMode);
149148
m3_LinkRawFunction (module, arduino, "digitalWrite", "v(ii)", &m3_arduino_digitalWrite);
150149

151-
// Convenience functions
150+
// Test functions
152151
m3_LinkRawFunction (module, arduino, "getPinLED", "i()", &m3_arduino_getPinLED);
153-
m3_LinkRawFunction (module, arduino, "print", "v(*)", &m3_arduino_print);
152+
m3_LinkRawFunction (module, arduino, "print", "v(*i)", &m3_arduino_print);
154153

155154
// Dummy (for TinyGo)
156155
m3_LinkRawFunction (module, "env", "io_get_stdout", "i()", &m3_dummy);
@@ -189,7 +188,13 @@ void wasm_task(void*)
189188
if (result) FATAL("LinkArduino", result);
190189

191190
IM3Function f;
192-
result = m3_FindFunction (&f, runtime, "_start");
191+
// Check for TinyGo entry function first
192+
// See https://github.com/tinygo-org/tinygo/issues/866
193+
result = m3_FindFunction (&f, runtime, "cwa_main");
194+
if (result) {
195+
result = m3_FindFunction (&f, runtime, "_start");
196+
}
197+
193198
if (result) FATAL("FindFunction", result);
194199

195200
Serial.println("Running WebAssembly...");

src/m3_compile.c

Lines changed: 79 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -48,29 +48,36 @@ i16 GetStackTopIndex (IM3Compilation o)
4848
}
4949

5050

51-
u8 GetStackTopType (IM3Compilation o)
51+
u8 GetStackTopTypeAtOffset (IM3Compilation o, u16 i_offset)
5252
{
5353
u8 type = c_m3Type_none;
54-
55-
if (o->stackIndex)
56-
type = o->typeStack [o->stackIndex - 1];
57-
54+
55+
++i_offset;
56+
if (o->stackIndex >= i_offset)
57+
type = o->typeStack [o->stackIndex - i_offset];
58+
5859
return type;
5960
}
6061

6162

62-
u8 GetStackType (IM3Compilation o, u16 i_offset)
63+
u8 GetStackTopType (IM3Compilation o)
6364
{
64-
u8 type = c_m3Type_none;
65+
return GetStackTopTypeAtOffset (o, 0);
66+
}
6567

66-
++i_offset;
67-
if (o->stackIndex > i_offset)
68-
type = o->typeStack [o->stackIndex - i_offset];
6968

69+
u8 GetStackBottomType (IM3Compilation o, u16 i_offset)
70+
{
71+
u8 type = c_m3Type_none;
72+
73+
if (i_offset < o->stackIndex)
74+
type = o->typeStack [i_offset];
75+
7076
return type;
7177
}
7278

7379

80+
7481
u8 GetBlockType (IM3Compilation o)
7582
{
7683
return o->block.type;
@@ -83,17 +90,6 @@ bool BlockHasType (IM3Compilation o)
8390
}
8491

8592

86-
bool IsStackTopTypeInt (IM3Compilation o)
87-
{
88-
return IsIntType (GetStackTopType (o));
89-
}
90-
91-
92-
bool IsStackTopTypeFp (IM3Compilation o)
93-
{
94-
return IsFpType (GetStackTopType (o));
95-
}
96-
9793
i16 GetNumBlockValues (IM3Compilation o)
9894
{
9995
return o->stackIndex - o->block.initStackIndex;
@@ -599,12 +595,15 @@ M3Result PreservedCopyTopSlot (IM3Compilation o, u16 i_destSlot, u16 i_preserv
599595

600596
IM3Operation op;
601597

598+
u8 type = GetStackTopType (o);
599+
602600
if (IsStackTopInRegister (o))
603601
{
604-
bool isFp = IsStackTopTypeFp (o);
605-
op = isFp ? op_PreserveSetSlot_f64 : op_PreserveSetSlot_i64;
602+
const IM3Operation c_preserveSetSlot [] = { NULL, op_PreserveSetSlot_i32, op_PreserveSetSlot_i64, op_PreserveSetSlot_f32, op_PreserveSetSlot_f64 };
603+
604+
op = c_preserveSetSlot [type];
606605
}
607-
else op = op_PreserveCopySlot_64;
606+
else op = Is64BitType (type) ? op_PreserveCopySlot_64 : op_PreserveCopySlot_32;
608607

609608
_ (EmitOp (o, op));
610609
EmitSlotOffset (o, i_destSlot);
@@ -663,22 +662,22 @@ M3Result ReturnStackTop (IM3Compilation o)
663662

664663

665664
// if local is unreferenced, o_preservedSlotIndex will be equal to localIndex on return
666-
M3Result FindReferencedLocalsWithCurrentBlock (IM3Compilation o, u16 * o_preservedSlotIndex, u32 i_localIndex)
665+
M3Result FindReferencedLocalWithinCurrentBlock (IM3Compilation o, u16 * o_preservedSlotIndex, u32 i_localIndex)
667666
{
668667
M3Result result = m3Err_none;
669668

670-
IM3CompilationScope scope = & o->block;
671-
i16 startIndex = scope->initStackIndex;
669+
IM3CompilationScope scope = & o->block;
670+
i16 startIndex = scope->initStackIndex;
672671

673-
while (scope->opcode == c_waOp_block)
674-
{
675-
scope = scope->outer;
676-
if (not scope)
677-
break;
672+
while (scope->opcode == c_waOp_block)
673+
{
674+
scope = scope->outer;
675+
if (not scope)
676+
break;
678677

679-
startIndex = scope->initStackIndex;
680-
}
681-
678+
startIndex = scope->initStackIndex;
679+
}
680+
682681
* o_preservedSlotIndex = (u16) i_localIndex;
683682

684683
for (u32 i = startIndex; i < o->stackIndex; ++i)
@@ -802,8 +801,7 @@ _ (EmitOp (o, op_Return));
802801
}
803802

804803

805-
// todo: else maps to nop now.
806-
M3Result Compile_Else_End (IM3Compilation o, u8 i_opcode)
804+
M3Result Compile_End (IM3Compilation o, u8 i_opcode)
807805
{
808806
M3Result result = m3Err_none;
809807

@@ -856,7 +854,7 @@ _ (ReadLEB_u32 (& localSlot, & o->wasm, o->wasmEnd)); // printf (
856854
if (localSlot < GetFunctionNumArgsAndLocals (o->function))
857855
{
858856
u16 preserveSlot;
859-
_ (FindReferencedLocalsWithCurrentBlock (o, & preserveSlot, localSlot)); // preserve will be different than local, if referenced
857+
_ (FindReferencedLocalWithinCurrentBlock (o, & preserveSlot, localSlot)); // preserve will be different than local, if referenced
860858

861859
if (preserveSlot == localSlot)
862860
_ (CopyTopSlot (o, localSlot))
@@ -906,16 +904,20 @@ M3Result Compile_SetGlobal (IM3Compilation o, M3Global * i_global)
906904
if (i_global->isMutable)
907905
{
908906
IM3Operation op;
907+
u8 type = GetStackTopType (o);
909908

910909
if (IsStackTopInRegister (o))
911-
op = IsStackTopTypeFp (o) ? op_SetGlobal_f64 : op_SetGlobal_i;
912-
else
913-
op = op_SetGlobal_s;
910+
{
911+
const IM3Operation c_setGlobalOps [] = { NULL, op_SetGlobal_i32, op_SetGlobal_i64, op_SetGlobal_f32, op_SetGlobal_f64 };
912+
913+
op = c_setGlobalOps [type];
914+
}
915+
else op = Is64BitType (type) ? op_SetGlobal_s64 : op_SetGlobal_s32;
914916

915917
_ (EmitOp (o, op));
916918
EmitPointer (o, & i_global->intValue);
917919

918-
if (op == op_SetGlobal_s)
920+
if (IsStackTopInSlot (o))
919921
EmitSlotOffset (o, GetStackTopSlotIndex (o));
920922

921923
_ (Pop (o));
@@ -1289,11 +1291,11 @@ M3Result PreserveArgsAndLocals (IM3Compilation o)
12891291
for (u32 i = 0; i < numArgsAndLocals; ++i)
12901292
{
12911293
u16 preservedSlotIndex;
1292-
_ (FindReferencedLocalsWithCurrentBlock (o, & preservedSlotIndex, i));
1294+
_ (FindReferencedLocalWithinCurrentBlock (o, & preservedSlotIndex, i));
12931295

12941296
if (preservedSlotIndex != i)
12951297
{
1296-
u8 type = GetStackType (o, i);
1298+
u8 type = GetStackBottomType (o, i);
12971299
IM3Operation op = Is64BitType (type) ? op_CopySlot_64 : op_CopySlot_32;
12981300

12991301
EmitOp (o, op);
@@ -1402,13 +1404,11 @@ M3Result Compile_Select (IM3Compilation o, u8 i_opcode)
14021404
{ op_Select_f32_rss, op_Select_f32_rrs, op_Select_f32_rsr } }, // selector in reg
14031405
{ { op_Select_f64_sss, op_Select_f64_srs, op_Select_f64_ssr }, // selector in slot
14041406
{ op_Select_f64_rss, op_Select_f64_rrs, op_Select_f64_rsr } } }; // selector in reg
1405-
1406-
14071407
M3Result result = m3Err_none;
14081408

14091409
u16 slots [3] = { c_slotUnused, c_slotUnused, c_slotUnused };
14101410

1411-
u8 type = GetStackType (o, 1); // get type of selection
1411+
u8 type = GetStackTopTypeAtOffset (o, 1); // get type of selection
14121412

14131413
IM3Operation op = NULL;
14141414

@@ -1627,13 +1627,14 @@ _ (Compile_Operator (o, i_opcode));
16271627
}
16281628

16291629

1630-
#define d_singleOp(OP) { op_##OP, NULL, NULL, NULL } // these aren't actually used by the compiler, just codepage decoding
1631-
#define d_emptyOpList() { NULL, NULL, NULL, NULL }
1632-
#define d_unaryOpList(TYPE, NAME) { op_##TYPE##_##NAME##_r, op_##TYPE##_##NAME##_s, NULL, NULL }
1633-
#define d_binOpList(TYPE, NAME) { op_##TYPE##_##NAME##_sr, op_##TYPE##_##NAME##_rs, op_##TYPE##_##NAME##_ss, NULL }
1634-
#define d_storeFpOpList(TYPE, NAME) { op_##TYPE##_##NAME##_sr, op_##TYPE##_##NAME##_rs, op_##TYPE##_##NAME##_ss, op_##TYPE##_##NAME##_rr }
1635-
#define d_commutativeBinOpList(TYPE, NAME) { op_##TYPE##_##NAME##_sr, NULL, op_##TYPE##_##NAME##_ss, NULL }
1636-
#define d_convertOpList(OP) { op_##OP##_r_r, op_##OP##_r_s, op_##OP##_s_r, op_##OP##_s_s }
1630+
// d_singleOp macros aren't actually used by the compiler, just codepage decoding
1631+
#define d_singleOp(OP) { op_##OP, NULL, NULL, NULL }
1632+
#define d_emptyOpList() { NULL, NULL, NULL, NULL }
1633+
#define d_unaryOpList(TYPE, NAME) { op_##TYPE##_##NAME##_r, op_##TYPE##_##NAME##_s, NULL, NULL }
1634+
#define d_binOpList(TYPE, NAME) { op_##TYPE##_##NAME##_rs, op_##TYPE##_##NAME##_sr, op_##TYPE##_##NAME##_ss, NULL }
1635+
#define d_storeFpOpList(TYPE, NAME) { op_##TYPE##_##NAME##_rs, op_##TYPE##_##NAME##_sr, op_##TYPE##_##NAME##_ss, op_##TYPE##_##NAME##_rr }
1636+
#define d_commutativeBinOpList(TYPE, NAME) { op_##TYPE##_##NAME##_rs, NULL, op_##TYPE##_##NAME##_ss, NULL }
1637+
#define d_convertOpList(OP) { op_##OP##_r_r, op_##OP##_r_s, op_##OP##_s_r, op_##OP##_s_s }
16371638

16381639

16391640
const M3OpInfo c_operations [] =
@@ -1643,11 +1644,11 @@ const M3OpInfo c_operations [] =
16431644
M3OP( "block", 0, none, d_emptyOpList(), Compile_LoopOrBlock ), // 0x02
16441645
M3OP( "loop", 0, none, d_singleOp (Loop), Compile_LoopOrBlock ), // 0x03
16451646
M3OP( "if", -1, none, d_emptyOpList(), Compile_If ), // 0x04
1646-
M3OP( "else", 0, none, d_emptyOpList(), Compile_Else_End ), // 0x05
1647+
M3OP( "else", 0, none, d_emptyOpList(), Compile_Nop ), // 0x05
16471648

16481649
M3OP_RESERVED, M3OP_RESERVED, M3OP_RESERVED, M3OP_RESERVED, M3OP_RESERVED, // 0x06 - 0x0a
16491650

1650-
M3OP( "end", 0, none, d_emptyOpList(), Compile_Else_End ), // 0x0b
1651+
M3OP( "end", 0, none, d_emptyOpList(), Compile_End ), // 0x0b
16511652
M3OP( "br", 0, none, d_singleOp (Branch), Compile_Branch ), // 0x0c
16521653
M3OP( "br_if", -1, none, { op_BranchIf_r, op_BranchIf_s }, Compile_Branch ), // 0x0d
16531654
M3OP( "br_table", -1, none, d_singleOp (BranchTable), Compile_BranchTable ), // 0x0e
@@ -1669,7 +1670,7 @@ const M3OpInfo c_operations [] =
16691670
M3OP( "local.set", 1, none, d_emptyOpList(), Compile_SetLocal ), // 0x21
16701671
M3OP( "local.tee", 0, any, d_emptyOpList(), Compile_SetLocal ), // 0x22
16711672
M3OP( "global.get", 1, none, d_singleOp (GetGlobal), Compile_GetSetGlobal ), // 0x23
1672-
M3OP( "global.set", 1, none, { op_SetGlobal_i, op_SetGlobal_s }, Compile_GetSetGlobal ), // 0x24
1673+
M3OP( "global.set", 1, none, d_emptyOpList(), Compile_GetSetGlobal ), // 0x24
16731674

16741675
M3OP_RESERVED, M3OP_RESERVED, M3OP_RESERVED, // 0x25 - 0x27
16751676

@@ -1853,21 +1854,32 @@ const M3OpInfo c_operations [] =
18531854
M3OP( "f32.reinterpret/i32", 0, f_32, d_convertOpList (f32_Reinterpret_i32), Compile_Convert ), // 0xbe
18541855
M3OP( "f64.reinterpret/i64", 0, f_64, d_convertOpList (f64_Reinterpret_i64), Compile_Convert ), // 0xbf
18551856

1857+
// instr ::= ...
1858+
// | 0xC0 => i32.extend8_s
1859+
// | 0xC1 => i32.extend16_s
1860+
// | 0xC2 => i64.extend8_s
1861+
// | 0xC3 => i64.extend16_s
1862+
// | 0xC4 => i64.extend32_s
1863+
//
1864+
M3OP( "i32.extend8_s", 0, i_32, d_unaryOpList (i32, Extend8_s) ), // 0xc0
1865+
M3OP( "i32.extend16_s", 0, i_32, d_unaryOpList (i32, Extend16_s) ), // 0xc1
1866+
M3OP( "i64.extend8_s", 0, i_64, d_unaryOpList (i64, Extend8_s) ), // 0xc2
1867+
M3OP( "i64.extend16_s", 0, i_64, d_unaryOpList (i64, Extend16_s) ), // 0xc3
1868+
M3OP( "i64.extend32_s", 0, i_64, d_unaryOpList (i64, Extend32_s) ), // 0xc4
1869+
18561870
# ifdef DEBUG // for codepage logging:
18571871
# define d_m3DebugOp(OP) M3OP (#OP, 0, none, { op_##OP })
1872+
# define d_m3DebugTypedOp(OP) M3OP (#OP, 0, none, { op_##OP##_i32, op_##OP##_i64, op_##OP##_f32, op_##OP##_f64, })
18581873

18591874
d_m3DebugOp (Const), d_m3DebugOp (Entry), d_m3DebugOp (Compile),
1860-
d_m3DebugOp (Bridge), d_m3DebugOp (End), d_m3DebugOp (SetGlobal_s),
1875+
d_m3DebugOp (Bridge), d_m3DebugOp (End),
18611876

18621877
d_m3DebugOp (ContinueLoop), d_m3DebugOp (ContinueLoopIf),
18631878

1864-
d_m3DebugOp (CopySlot_32), // d_m3DebugOp (PreserveCopySlot_32),
1879+
d_m3DebugOp (CopySlot_32), d_m3DebugOp (PreserveCopySlot_32),
18651880
d_m3DebugOp (CopySlot_64), d_m3DebugOp (PreserveCopySlot_64),
18661881

1867-
d_m3DebugOp (SetRegister_i32), d_m3DebugOp (i32_BranchIf_rs), d_m3DebugOp (SetSlot_i32),
1868-
d_m3DebugOp (SetRegister_i64), d_m3DebugOp (i32_BranchIf_ss), d_m3DebugOp (SetSlot_i64),
1869-
d_m3DebugOp (SetRegister_f32), d_m3DebugOp (i64_BranchIf_rs), d_m3DebugOp (SetSlot_f32),
1870-
d_m3DebugOp (SetRegister_f64), d_m3DebugOp (i64_BranchIf_ss), d_m3DebugOp (SetSlot_f64),
1882+
d_m3DebugOp (i32_BranchIf_rs), d_m3DebugOp (i32_BranchIf_ss), d_m3DebugOp (i64_BranchIf_rs), d_m3DebugOp (i64_BranchIf_ss),
18711883

18721884
d_m3DebugOp (Select_i32_rss), d_m3DebugOp (Select_i32_srs), d_m3DebugOp (Select_i32_ssr), d_m3DebugOp (Select_i32_sss),
18731885
d_m3DebugOp (Select_i64_rss), d_m3DebugOp (Select_i64_srs), d_m3DebugOp (Select_i64_ssr), d_m3DebugOp (Select_i64_sss),
@@ -1878,6 +1890,10 @@ const M3OpInfo c_operations [] =
18781890
d_m3DebugOp (Select_f64_sss), d_m3DebugOp (Select_f64_srs), d_m3DebugOp (Select_f64_ssr),
18791891
d_m3DebugOp (Select_f64_rss), d_m3DebugOp (Select_f64_rrs), d_m3DebugOp (Select_f64_rsr),
18801892

1893+
d_m3DebugTypedOp (SetGlobal), d_m3DebugOp (SetGlobal_s32), d_m3DebugOp (SetGlobal_s64),
1894+
1895+
d_m3DebugTypedOp (SetRegister), d_m3DebugTypedOp (SetSlot), d_m3DebugTypedOp (PreserveSetSlot),
1896+
18811897
# endif
18821898

18831899
M3OP( "termination", 0, c_m3Type_void ) // termination for find_operation_info ()

src/m3_config_platforms.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -220,8 +220,12 @@ typedef int8_t i8;
220220
# include <c_types.h>
221221
# define op_section //ICACHE_FLASH_ATTR
222222
# elif defined (ESP32)
223-
# include "esp_system.h"
224-
# define op_section IRAM_ATTR
223+
# if defined(M3_IN_IRAM) // the interpreter is in IRAM, attribute not needed
224+
# define op_section
225+
# else
226+
# include "esp_system.h"
227+
# define op_section IRAM_ATTR
228+
# endif
225229
# elif defined (FOMU)
226230
# define op_section __attribute__((section(".ramtext")))
227231
# endif

0 commit comments

Comments
 (0)