1+ #include < Arduino.h>
2+
3+ #include < cstddef>
4+ #include < cstdint>
5+ #include < cstdlib>
6+ #include < cstring>
7+ #include < limits>
8+
9+ #include " program_vmbc.h"
10+ #include " rustscript_embedded.h"
11+
12+ namespace {
13+
14+ bool host_name_equals (const uint8_t *name, size_t name_len, const char *expected) {
15+ const size_t expected_len = std::strlen (expected);
16+ return name_len == expected_len && std::memcmp (name, expected, expected_len) == 0 ;
17+ }
18+
19+ int32_t return_bool (rustscript_value *result, bool value) {
20+ if (result == nullptr ) {
21+ return -1 ;
22+ }
23+ *result = {};
24+ result->tag = RUSTSCRIPT_VALUE_BOOL ;
25+ result->boolean = value ? 1 : 0 ;
26+ return 1 ;
27+ }
28+
29+ int32_t dispatch_host (
30+ void *,
31+ const uint8_t *name,
32+ size_t name_len,
33+ const rustscript_value *args,
34+ size_t arg_count,
35+ rustscript_value *result
36+ ) {
37+ if (host_name_equals (name, name_len, " gpio::configure" ) && arg_count == 2 &&
38+ args[0 ].tag == RUSTSCRIPT_VALUE_INT && args[1 ].tag == RUSTSCRIPT_VALUE_INT ) {
39+ pinMode (static_cast <uint8_t >(args[0 ].integer ), static_cast <uint8_t >(args[1 ].integer ));
40+ return return_bool (result, true );
41+ }
42+ if (host_name_equals (name, name_len, " gpio::digital_write" ) && arg_count == 2 &&
43+ args[0 ].tag == RUSTSCRIPT_VALUE_INT && args[1 ].tag == RUSTSCRIPT_VALUE_BOOL ) {
44+ digitalWrite (static_cast <uint8_t >(args[0 ].integer ), args[1 ].boolean ? HIGH : LOW );
45+ return return_bool (result, true );
46+ }
47+ if (host_name_equals (name, name_len, " gpio::digital_read" ) && arg_count == 1 &&
48+ args[0 ].tag == RUSTSCRIPT_VALUE_INT ) {
49+ return return_bool (result, digitalRead (static_cast <uint8_t >(args[0 ].integer )) == HIGH );
50+ }
51+ if (host_name_equals (name, name_len, " mcu::delay_ms" ) && arg_count == 1 &&
52+ args[0 ].tag == RUSTSCRIPT_VALUE_INT && args[0 ].integer >= 0 ) {
53+ delay (static_cast <unsigned long >(args[0 ].integer ));
54+ return 0 ;
55+ }
56+ if (host_name_equals (name, name_len, " serial::write_line" ) && arg_count == 1 &&
57+ args[0 ].tag == RUSTSCRIPT_VALUE_STRING ) {
58+ Serial.write (args[0 ].data , args[0 ].len );
59+ Serial.println ();
60+ return 0 ;
61+ }
62+ return -1 ;
63+ }
64+
65+ } // namespace
66+
67+ extern " C" void *rustscript_platform_alloc (size_t size, size_t align) {
68+ if (size == 0 || align == 0 || (align & (align - 1 )) != 0 ) {
69+ return nullptr ;
70+ }
71+ if (align <= alignof (std::max_align_t )) {
72+ return std::malloc (size);
73+ }
74+ if (size > std::numeric_limits<size_t >::max () - align - sizeof (void *)) {
75+ return nullptr ;
76+ }
77+ void *raw = std::malloc (size + align - 1 + sizeof (void *));
78+ if (raw == nullptr ) {
79+ return nullptr ;
80+ }
81+ const uintptr_t start = reinterpret_cast <uintptr_t >(raw) + sizeof (void *);
82+ const uintptr_t aligned = (start + align - 1 ) & ~(static_cast <uintptr_t >(align) - 1 );
83+ reinterpret_cast <void **>(aligned)[-1 ] = raw;
84+ return reinterpret_cast <void *>(aligned);
85+ }
86+
87+ extern " C" void rustscript_platform_dealloc (void *pointer, size_t , size_t align) {
88+ if (pointer == nullptr ) {
89+ return ;
90+ }
91+ if (align <= alignof (std::max_align_t )) {
92+ std::free (pointer);
93+ } else {
94+ std::free (reinterpret_cast <void **>(pointer)[-1 ]);
95+ }
96+ }
97+
98+ void setup () {
99+ Serial.begin (115200 );
100+ const int32_t status = rustscript_run_vmbc (
101+ RUSTSCRIPT_PROGRAM_VMBC ,
102+ RUSTSCRIPT_PROGRAM_VMBC_LEN ,
103+ dispatch_host,
104+ nullptr ,
105+ 1000000
106+ );
107+ Serial.print (" rss:status=" );
108+ Serial.println (status);
109+ }
110+
111+ void loop () {
112+ delay (1000 );
113+ }
0 commit comments