xref: /aosp_15_r20/external/swiftshader/third_party/subzero/runtime/wasm-runtime.cpp (revision 03ce13f70fcc45d86ee91b7ee4cab1936a95046e)
1*03ce13f7SAndroid Build Coastguard Worker //===- subzero/runtime/wasm-runtime.cpp - Subzero WASM runtime source -----===//
2*03ce13f7SAndroid Build Coastguard Worker //
3*03ce13f7SAndroid Build Coastguard Worker //                        The Subzero Code Generator
4*03ce13f7SAndroid Build Coastguard Worker //
5*03ce13f7SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*03ce13f7SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*03ce13f7SAndroid Build Coastguard Worker //
8*03ce13f7SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*03ce13f7SAndroid Build Coastguard Worker //
10*03ce13f7SAndroid Build Coastguard Worker // This file implements the system calls required by the libc that is included
11*03ce13f7SAndroid Build Coastguard Worker // in WebAssembly programs.
12*03ce13f7SAndroid Build Coastguard Worker //
13*03ce13f7SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
14*03ce13f7SAndroid Build Coastguard Worker 
15*03ce13f7SAndroid Build Coastguard Worker #include <algorithm>
16*03ce13f7SAndroid Build Coastguard Worker #include <cassert>
17*03ce13f7SAndroid Build Coastguard Worker #include <cmath>
18*03ce13f7SAndroid Build Coastguard Worker #include <iostream>
19*03ce13f7SAndroid Build Coastguard Worker #include <vector>
20*03ce13f7SAndroid Build Coastguard Worker 
21*03ce13f7SAndroid Build Coastguard Worker #include <errno.h>
22*03ce13f7SAndroid Build Coastguard Worker #include <fcntl.h>
23*03ce13f7SAndroid Build Coastguard Worker #include <math.h>
24*03ce13f7SAndroid Build Coastguard Worker #include <stdint.h>
25*03ce13f7SAndroid Build Coastguard Worker #include <stdio.h>
26*03ce13f7SAndroid Build Coastguard Worker #include <stdlib.h>
27*03ce13f7SAndroid Build Coastguard Worker #include <string.h>
28*03ce13f7SAndroid Build Coastguard Worker #include <sys/ioctl.h>
29*03ce13f7SAndroid Build Coastguard Worker #include <sys/stat.h>
30*03ce13f7SAndroid Build Coastguard Worker #include <sys/types.h>
31*03ce13f7SAndroid Build Coastguard Worker #include <termios.h>
32*03ce13f7SAndroid Build Coastguard Worker #include <time.h>
33*03ce13f7SAndroid Build Coastguard Worker #include <unistd.h>
34*03ce13f7SAndroid Build Coastguard Worker 
35*03ce13f7SAndroid Build Coastguard Worker #ifdef WASM_TRACE_RUNTIME
36*03ce13f7SAndroid Build Coastguard Worker #define TRACE_ENTRY()                                                          \
37*03ce13f7SAndroid Build Coastguard Worker   { std::cerr << __func__ << "(...) = "; }
trace(T x)38*03ce13f7SAndroid Build Coastguard Worker template <typename T> T trace(T x) {
39*03ce13f7SAndroid Build Coastguard Worker   std::cerr << x << std::endl;
40*03ce13f7SAndroid Build Coastguard Worker   return x;
41*03ce13f7SAndroid Build Coastguard Worker }
trace()42*03ce13f7SAndroid Build Coastguard Worker void trace() { std::cerr << "(void)" << std::endl; }
43*03ce13f7SAndroid Build Coastguard Worker #else
44*03ce13f7SAndroid Build Coastguard Worker #define TRACE_ENTRY()
trace(T x)45*03ce13f7SAndroid Build Coastguard Worker template <typename T> T trace(T x) { return x; }
trace()46*03ce13f7SAndroid Build Coastguard Worker void trace() {}
47*03ce13f7SAndroid Build Coastguard Worker #endif // WASM_TRACE_RUNTIME
48*03ce13f7SAndroid Build Coastguard Worker 
49*03ce13f7SAndroid Build Coastguard Worker extern "C" {
50*03ce13f7SAndroid Build Coastguard Worker char *WASM_MEMORY;
51*03ce13f7SAndroid Build Coastguard Worker extern uint32_t WASM_DATA_SIZE;
52*03ce13f7SAndroid Build Coastguard Worker extern uint32_t WASM_NUM_PAGES;
53*03ce13f7SAndroid Build Coastguard Worker } // end of extern "C"
54*03ce13f7SAndroid Build Coastguard Worker 
55*03ce13f7SAndroid Build Coastguard Worker namespace {
56*03ce13f7SAndroid Build Coastguard Worker uint32_t HeapBreak;
57*03ce13f7SAndroid Build Coastguard Worker 
58*03ce13f7SAndroid Build Coastguard Worker // TODO (eholk): make all of these constexpr.
59*03ce13f7SAndroid Build Coastguard Worker const uint32_t PageSizeLog2 = 16;
60*03ce13f7SAndroid Build Coastguard Worker const uint32_t PageSize = 1 << PageSizeLog2; // 64KB
61*03ce13f7SAndroid Build Coastguard Worker const uint32_t StackPtrLoc = 1024;           // defined by emscripten
62*03ce13f7SAndroid Build Coastguard Worker 
pageNum(uint32_t Index)63*03ce13f7SAndroid Build Coastguard Worker uint32_t pageNum(uint32_t Index) { return Index >> PageSizeLog2; }
64*03ce13f7SAndroid Build Coastguard Worker } // end of anonymous namespace
65*03ce13f7SAndroid Build Coastguard Worker 
66*03ce13f7SAndroid Build Coastguard Worker namespace env {
floor(double X)67*03ce13f7SAndroid Build Coastguard Worker double floor(double X) { return std::floor(X); }
68*03ce13f7SAndroid Build Coastguard Worker 
floor(float X)69*03ce13f7SAndroid Build Coastguard Worker float floor(float X) { return std::floor(X); }
70*03ce13f7SAndroid Build Coastguard Worker } // end of namespace env
71*03ce13f7SAndroid Build Coastguard Worker 
72*03ce13f7SAndroid Build Coastguard Worker // TODO (eholk): move the C parts outside and use C++ name mangling.
73*03ce13f7SAndroid Build Coastguard Worker 
74*03ce13f7SAndroid Build Coastguard Worker namespace {
75*03ce13f7SAndroid Build Coastguard Worker 
76*03ce13f7SAndroid Build Coastguard Worker /// Some runtime functions need to return pointers. The WasmData struct is used
77*03ce13f7SAndroid Build Coastguard Worker /// to preallocate space for these on the heap.
78*03ce13f7SAndroid Build Coastguard Worker struct WasmData {
79*03ce13f7SAndroid Build Coastguard Worker 
80*03ce13f7SAndroid Build Coastguard Worker   /// StrBuf is returned by functions that return strings.
81*03ce13f7SAndroid Build Coastguard Worker   char StrBuf[256];
82*03ce13f7SAndroid Build Coastguard Worker };
83*03ce13f7SAndroid Build Coastguard Worker 
84*03ce13f7SAndroid Build Coastguard Worker WasmData *GlobalData = NULL;
85*03ce13f7SAndroid Build Coastguard Worker 
toWasm(void * Ptr)86*03ce13f7SAndroid Build Coastguard Worker int toWasm(void *Ptr) {
87*03ce13f7SAndroid Build Coastguard Worker   return reinterpret_cast<int>(reinterpret_cast<char *>(Ptr) - WASM_MEMORY);
88*03ce13f7SAndroid Build Coastguard Worker }
89*03ce13f7SAndroid Build Coastguard Worker 
wasmPtr(int Index)90*03ce13f7SAndroid Build Coastguard Worker template <typename T> T *wasmPtr(int Index) {
91*03ce13f7SAndroid Build Coastguard Worker   if (pageNum(Index) < WASM_NUM_PAGES) {
92*03ce13f7SAndroid Build Coastguard Worker     return reinterpret_cast<T *>(WASM_MEMORY + Index);
93*03ce13f7SAndroid Build Coastguard Worker   }
94*03ce13f7SAndroid Build Coastguard Worker   abort();
95*03ce13f7SAndroid Build Coastguard Worker }
96*03ce13f7SAndroid Build Coastguard Worker 
97*03ce13f7SAndroid Build Coastguard Worker template <typename T> class WasmPtr {
98*03ce13f7SAndroid Build Coastguard Worker   int Ptr;
99*03ce13f7SAndroid Build Coastguard Worker 
100*03ce13f7SAndroid Build Coastguard Worker public:
WasmPtr(int Ptr)101*03ce13f7SAndroid Build Coastguard Worker   WasmPtr(int Ptr) : Ptr(Ptr) {
102*03ce13f7SAndroid Build Coastguard Worker     // TODO (eholk): make this a static_assert once we have C++11
103*03ce13f7SAndroid Build Coastguard Worker     assert(sizeof(*this) == sizeof(int));
104*03ce13f7SAndroid Build Coastguard Worker   }
105*03ce13f7SAndroid Build Coastguard Worker 
WasmPtr(T * Ptr)106*03ce13f7SAndroid Build Coastguard Worker   WasmPtr(T *Ptr) : Ptr(toWasm(Ptr)) {}
107*03ce13f7SAndroid Build Coastguard Worker 
operator *() const108*03ce13f7SAndroid Build Coastguard Worker   T &operator*() const { return *asPtr(); }
109*03ce13f7SAndroid Build Coastguard Worker 
asPtr() const110*03ce13f7SAndroid Build Coastguard Worker   T *asPtr() const { return wasmPtr<T>(Ptr); }
111*03ce13f7SAndroid Build Coastguard Worker 
asInt() const112*03ce13f7SAndroid Build Coastguard Worker   int asInt() const { return Ptr; }
113*03ce13f7SAndroid Build Coastguard Worker };
114*03ce13f7SAndroid Build Coastguard Worker 
115*03ce13f7SAndroid Build Coastguard Worker typedef WasmPtr<char> WasmCharPtr;
116*03ce13f7SAndroid Build Coastguard Worker 
117*03ce13f7SAndroid Build Coastguard Worker template <typename T> class WasmArray {
118*03ce13f7SAndroid Build Coastguard Worker   int Ptr;
119*03ce13f7SAndroid Build Coastguard Worker 
120*03ce13f7SAndroid Build Coastguard Worker public:
WasmArray(int Ptr)121*03ce13f7SAndroid Build Coastguard Worker   WasmArray(int Ptr) : Ptr(Ptr) {
122*03ce13f7SAndroid Build Coastguard Worker     // TODO (eholk): make this a static_assert once we have C++11.
123*03ce13f7SAndroid Build Coastguard Worker     assert(sizeof(*this) == sizeof(int));
124*03ce13f7SAndroid Build Coastguard Worker   }
125*03ce13f7SAndroid Build Coastguard Worker 
operator [](unsigned int Index) const126*03ce13f7SAndroid Build Coastguard Worker   T &operator[](unsigned int Index) const { return wasmPtr<T>(Ptr)[Index]; }
127*03ce13f7SAndroid Build Coastguard Worker };
128*03ce13f7SAndroid Build Coastguard Worker } // end of anonymous namespace
129*03ce13f7SAndroid Build Coastguard Worker 
130*03ce13f7SAndroid Build Coastguard Worker // TODO (eholk): move the C parts outside and use C++ name mangling.
131*03ce13f7SAndroid Build Coastguard Worker extern "C" {
132*03ce13f7SAndroid Build Coastguard Worker 
__Sz_bounds_fail()133*03ce13f7SAndroid Build Coastguard Worker void __Sz_bounds_fail() {
134*03ce13f7SAndroid Build Coastguard Worker   std::cerr << "Bounds check failure" << std::endl;
135*03ce13f7SAndroid Build Coastguard Worker   abort();
136*03ce13f7SAndroid Build Coastguard Worker }
137*03ce13f7SAndroid Build Coastguard Worker 
__Sz_indirect_fail()138*03ce13f7SAndroid Build Coastguard Worker void __Sz_indirect_fail() {
139*03ce13f7SAndroid Build Coastguard Worker   std::cerr << "Invalid indirect call target" << std::endl;
140*03ce13f7SAndroid Build Coastguard Worker   abort();
141*03ce13f7SAndroid Build Coastguard Worker }
142*03ce13f7SAndroid Build Coastguard Worker 
143*03ce13f7SAndroid Build Coastguard Worker extern char WASM_DATA_INIT[];
144*03ce13f7SAndroid Build Coastguard Worker 
env$$abort()145*03ce13f7SAndroid Build Coastguard Worker void env$$abort() {
146*03ce13f7SAndroid Build Coastguard Worker   fprintf(stderr, "Aborting...\n");
147*03ce13f7SAndroid Build Coastguard Worker   abort();
148*03ce13f7SAndroid Build Coastguard Worker }
149*03ce13f7SAndroid Build Coastguard Worker 
env$$_abort()150*03ce13f7SAndroid Build Coastguard Worker void env$$_abort() { env$$abort(); }
151*03ce13f7SAndroid Build Coastguard Worker 
env$$floor_f(float X)152*03ce13f7SAndroid Build Coastguard Worker double env$$floor_f(float X) {
153*03ce13f7SAndroid Build Coastguard Worker   TRACE_ENTRY();
154*03ce13f7SAndroid Build Coastguard Worker   return env::floor(X);
155*03ce13f7SAndroid Build Coastguard Worker }
env$$floor_d(double X)156*03ce13f7SAndroid Build Coastguard Worker double env$$floor_d(double X) {
157*03ce13f7SAndroid Build Coastguard Worker   TRACE_ENTRY();
158*03ce13f7SAndroid Build Coastguard Worker   return env::floor(X);
159*03ce13f7SAndroid Build Coastguard Worker }
160*03ce13f7SAndroid Build Coastguard Worker 
env$$exit(int Status)161*03ce13f7SAndroid Build Coastguard Worker void env$$exit(int Status) {
162*03ce13f7SAndroid Build Coastguard Worker   TRACE_ENTRY();
163*03ce13f7SAndroid Build Coastguard Worker   exit(Status);
164*03ce13f7SAndroid Build Coastguard Worker }
env$$_exit(int Status)165*03ce13f7SAndroid Build Coastguard Worker void env$$_exit(int Status) {
166*03ce13f7SAndroid Build Coastguard Worker   TRACE_ENTRY();
167*03ce13f7SAndroid Build Coastguard Worker   env$$exit(Status);
168*03ce13f7SAndroid Build Coastguard Worker }
169*03ce13f7SAndroid Build Coastguard Worker 
170*03ce13f7SAndroid Build Coastguard Worker #define UNIMPLEMENTED(f)                                                       \
171*03ce13f7SAndroid Build Coastguard Worker   void env$$##f() {                                                            \
172*03ce13f7SAndroid Build Coastguard Worker     fprintf(stderr, "Unimplemented: " #f "\n");                                \
173*03ce13f7SAndroid Build Coastguard Worker     abort();                                                                   \
174*03ce13f7SAndroid Build Coastguard Worker   }
175*03ce13f7SAndroid Build Coastguard Worker 
env$$sbrk(int32_t Increment)176*03ce13f7SAndroid Build Coastguard Worker int32_t env$$sbrk(int32_t Increment) {
177*03ce13f7SAndroid Build Coastguard Worker   TRACE_ENTRY();
178*03ce13f7SAndroid Build Coastguard Worker   uint32_t OldBreak = HeapBreak;
179*03ce13f7SAndroid Build Coastguard Worker   HeapBreak += Increment;
180*03ce13f7SAndroid Build Coastguard Worker   return trace(OldBreak);
181*03ce13f7SAndroid Build Coastguard Worker }
182*03ce13f7SAndroid Build Coastguard Worker 
183*03ce13f7SAndroid Build Coastguard Worker UNIMPLEMENTED(__addtf3)
184*03ce13f7SAndroid Build Coastguard Worker UNIMPLEMENTED(__assert_fail)
185*03ce13f7SAndroid Build Coastguard Worker UNIMPLEMENTED(__builtin_apply)
186*03ce13f7SAndroid Build Coastguard Worker UNIMPLEMENTED(__builtin_apply_args)
187*03ce13f7SAndroid Build Coastguard Worker UNIMPLEMENTED(__builtin_isinff)
188*03ce13f7SAndroid Build Coastguard Worker UNIMPLEMENTED(__builtin_isinfl)
189*03ce13f7SAndroid Build Coastguard Worker UNIMPLEMENTED(__builtin_malloc)
190*03ce13f7SAndroid Build Coastguard Worker UNIMPLEMENTED(__divtf3)
191*03ce13f7SAndroid Build Coastguard Worker UNIMPLEMENTED(__eqtf2)
192*03ce13f7SAndroid Build Coastguard Worker UNIMPLEMENTED(__extenddftf2)
193*03ce13f7SAndroid Build Coastguard Worker UNIMPLEMENTED(__extendsftf2)
194*03ce13f7SAndroid Build Coastguard Worker UNIMPLEMENTED(__fixsfti)
195*03ce13f7SAndroid Build Coastguard Worker UNIMPLEMENTED(__fixtfdi)
196*03ce13f7SAndroid Build Coastguard Worker UNIMPLEMENTED(__fixtfsi)
197*03ce13f7SAndroid Build Coastguard Worker UNIMPLEMENTED(__fixunstfsi)
198*03ce13f7SAndroid Build Coastguard Worker UNIMPLEMENTED(__floatditf)
199*03ce13f7SAndroid Build Coastguard Worker UNIMPLEMENTED(__floatsitf)
200*03ce13f7SAndroid Build Coastguard Worker UNIMPLEMENTED(__floatunsitf)
201*03ce13f7SAndroid Build Coastguard Worker UNIMPLEMENTED(__getf2)
202*03ce13f7SAndroid Build Coastguard Worker UNIMPLEMENTED(__letf2)
203*03ce13f7SAndroid Build Coastguard Worker UNIMPLEMENTED(__lttf2)
204*03ce13f7SAndroid Build Coastguard Worker UNIMPLEMENTED(__multf3)
205*03ce13f7SAndroid Build Coastguard Worker UNIMPLEMENTED(__multi3)
206*03ce13f7SAndroid Build Coastguard Worker UNIMPLEMENTED(__netf2)
207*03ce13f7SAndroid Build Coastguard Worker UNIMPLEMENTED(__subtf3)
208*03ce13f7SAndroid Build Coastguard Worker UNIMPLEMENTED(__syscall140) // sys_llseek
209*03ce13f7SAndroid Build Coastguard Worker UNIMPLEMENTED(__syscall221) // sys_fcntl64
210*03ce13f7SAndroid Build Coastguard Worker UNIMPLEMENTED(__trunctfdf2)
211*03ce13f7SAndroid Build Coastguard Worker UNIMPLEMENTED(__trunctfsf2)
212*03ce13f7SAndroid Build Coastguard Worker UNIMPLEMENTED(__unordtf2)
213*03ce13f7SAndroid Build Coastguard Worker UNIMPLEMENTED(longjmp)
214*03ce13f7SAndroid Build Coastguard Worker UNIMPLEMENTED(pthread_cleanup_pop)
215*03ce13f7SAndroid Build Coastguard Worker UNIMPLEMENTED(pthread_cleanup_push)
216*03ce13f7SAndroid Build Coastguard Worker UNIMPLEMENTED(pthread_self)
217*03ce13f7SAndroid Build Coastguard Worker UNIMPLEMENTED(setjmp)
218*03ce13f7SAndroid Build Coastguard Worker 
219*03ce13f7SAndroid Build Coastguard Worker extern int __szwasm_main(int, WasmPtr<WasmCharPtr>);
220*03ce13f7SAndroid Build Coastguard Worker 
221*03ce13f7SAndroid Build Coastguard Worker #define WASM_REF(Type, Index) (WasmPtr<Type>(Index).asPtr())
222*03ce13f7SAndroid Build Coastguard Worker #define WASM_DEREF(Type, Index) (*WASM_REF(Type, Index))
223*03ce13f7SAndroid Build Coastguard Worker 
main(int argc,const char ** argv)224*03ce13f7SAndroid Build Coastguard Worker int main(int argc, const char **argv) {
225*03ce13f7SAndroid Build Coastguard Worker   // Create the heap.
226*03ce13f7SAndroid Build Coastguard Worker   std::vector<char> WasmHeap(WASM_NUM_PAGES << PageSizeLog2);
227*03ce13f7SAndroid Build Coastguard Worker   WASM_MEMORY = WasmHeap.data();
228*03ce13f7SAndroid Build Coastguard Worker   std::copy(WASM_DATA_INIT, WASM_DATA_INIT + WASM_DATA_SIZE, WasmHeap.begin());
229*03ce13f7SAndroid Build Coastguard Worker 
230*03ce13f7SAndroid Build Coastguard Worker   // TODO (eholk): align these allocations correctly.
231*03ce13f7SAndroid Build Coastguard Worker 
232*03ce13f7SAndroid Build Coastguard Worker   // Allocate space for the global data.
233*03ce13f7SAndroid Build Coastguard Worker   HeapBreak = WASM_DATA_SIZE;
234*03ce13f7SAndroid Build Coastguard Worker   GlobalData = WASM_REF(WasmData, HeapBreak);
235*03ce13f7SAndroid Build Coastguard Worker   HeapBreak += sizeof(WasmData);
236*03ce13f7SAndroid Build Coastguard Worker 
237*03ce13f7SAndroid Build Coastguard Worker   // copy the command line arguments.
238*03ce13f7SAndroid Build Coastguard Worker   WasmPtr<WasmCharPtr> WasmArgV = HeapBreak;
239*03ce13f7SAndroid Build Coastguard Worker   WasmPtr<char> *WasmArgVPtr = WasmArgV.asPtr();
240*03ce13f7SAndroid Build Coastguard Worker   HeapBreak += argc * sizeof(*WasmArgVPtr);
241*03ce13f7SAndroid Build Coastguard Worker 
242*03ce13f7SAndroid Build Coastguard Worker   for (int i = 0; i < argc; ++i) {
243*03ce13f7SAndroid Build Coastguard Worker     WasmArgVPtr[i] = HeapBreak;
244*03ce13f7SAndroid Build Coastguard Worker     strcpy(WASM_REF(char, HeapBreak), argv[i]);
245*03ce13f7SAndroid Build Coastguard Worker     HeapBreak += strlen(argv[i]) + 1;
246*03ce13f7SAndroid Build Coastguard Worker   }
247*03ce13f7SAndroid Build Coastguard Worker 
248*03ce13f7SAndroid Build Coastguard Worker   // Initialize the break to the nearest page boundary after the data segment
249*03ce13f7SAndroid Build Coastguard Worker   HeapBreak = (WASM_DATA_SIZE + PageSize - 1) & ~(PageSize - 1);
250*03ce13f7SAndroid Build Coastguard Worker 
251*03ce13f7SAndroid Build Coastguard Worker   // Initialize the stack pointer.
252*03ce13f7SAndroid Build Coastguard Worker   WASM_DEREF(int32_t, StackPtrLoc) = WASM_NUM_PAGES << PageSizeLog2;
253*03ce13f7SAndroid Build Coastguard Worker 
254*03ce13f7SAndroid Build Coastguard Worker   return __szwasm_main(argc, WasmArgV);
255*03ce13f7SAndroid Build Coastguard Worker }
256*03ce13f7SAndroid Build Coastguard Worker 
env$$abs(int a)257*03ce13f7SAndroid Build Coastguard Worker int env$$abs(int a) {
258*03ce13f7SAndroid Build Coastguard Worker   TRACE_ENTRY();
259*03ce13f7SAndroid Build Coastguard Worker   return trace(abs(a));
260*03ce13f7SAndroid Build Coastguard Worker }
261*03ce13f7SAndroid Build Coastguard Worker 
env$$clock()262*03ce13f7SAndroid Build Coastguard Worker clock_t env$$clock() {
263*03ce13f7SAndroid Build Coastguard Worker   TRACE_ENTRY();
264*03ce13f7SAndroid Build Coastguard Worker   return trace(clock());
265*03ce13f7SAndroid Build Coastguard Worker }
266*03ce13f7SAndroid Build Coastguard Worker 
env$$ctime(WasmPtr<time_t> Time)267*03ce13f7SAndroid Build Coastguard Worker int env$$ctime(WasmPtr<time_t> Time) {
268*03ce13f7SAndroid Build Coastguard Worker   TRACE_ENTRY();
269*03ce13f7SAndroid Build Coastguard Worker   char *CTime = ctime(Time.asPtr());
270*03ce13f7SAndroid Build Coastguard Worker   strncpy(GlobalData->StrBuf, CTime, sizeof(GlobalData->StrBuf));
271*03ce13f7SAndroid Build Coastguard Worker   GlobalData->StrBuf[sizeof(GlobalData->StrBuf) - 1] = '\0';
272*03ce13f7SAndroid Build Coastguard Worker   return trace(WasmPtr<char>(GlobalData->StrBuf).asInt());
273*03ce13f7SAndroid Build Coastguard Worker }
274*03ce13f7SAndroid Build Coastguard Worker 
env$$pow(double x,double y)275*03ce13f7SAndroid Build Coastguard Worker double env$$pow(double x, double y) {
276*03ce13f7SAndroid Build Coastguard Worker   TRACE_ENTRY();
277*03ce13f7SAndroid Build Coastguard Worker   return trace(pow(x, y));
278*03ce13f7SAndroid Build Coastguard Worker }
279*03ce13f7SAndroid Build Coastguard Worker 
env$$time(WasmPtr<time_t> Time)280*03ce13f7SAndroid Build Coastguard Worker time_t env$$time(WasmPtr<time_t> Time) {
281*03ce13f7SAndroid Build Coastguard Worker   TRACE_ENTRY();
282*03ce13f7SAndroid Build Coastguard Worker   time_t *TimePtr = WASM_REF(time_t, Time);
283*03ce13f7SAndroid Build Coastguard Worker   return trace(time(TimePtr));
284*03ce13f7SAndroid Build Coastguard Worker }
285*03ce13f7SAndroid Build Coastguard Worker 
286*03ce13f7SAndroid Build Coastguard Worker // lock and unlock are no-ops in wasm.js, so we mimic that behavior.
env$$__lock(int32_t)287*03ce13f7SAndroid Build Coastguard Worker void env$$__lock(int32_t) {
288*03ce13f7SAndroid Build Coastguard Worker   TRACE_ENTRY();
289*03ce13f7SAndroid Build Coastguard Worker   trace();
290*03ce13f7SAndroid Build Coastguard Worker }
291*03ce13f7SAndroid Build Coastguard Worker 
env$$__unlock(int32_t)292*03ce13f7SAndroid Build Coastguard Worker void env$$__unlock(int32_t) {
293*03ce13f7SAndroid Build Coastguard Worker   TRACE_ENTRY();
294*03ce13f7SAndroid Build Coastguard Worker   trace();
295*03ce13f7SAndroid Build Coastguard Worker }
296*03ce13f7SAndroid Build Coastguard Worker 
297*03ce13f7SAndroid Build Coastguard Worker /// sys_read
env$$__syscall3(int Which,WasmArray<int> VarArgs)298*03ce13f7SAndroid Build Coastguard Worker int env$$__syscall3(int Which, WasmArray<int> VarArgs) {
299*03ce13f7SAndroid Build Coastguard Worker   TRACE_ENTRY();
300*03ce13f7SAndroid Build Coastguard Worker   int Fd = VarArgs[0];
301*03ce13f7SAndroid Build Coastguard Worker   int Buffer = VarArgs[1];
302*03ce13f7SAndroid Build Coastguard Worker   int Length = VarArgs[2];
303*03ce13f7SAndroid Build Coastguard Worker 
304*03ce13f7SAndroid Build Coastguard Worker   return trace(read(Fd, WASM_REF(char *, Buffer), Length));
305*03ce13f7SAndroid Build Coastguard Worker }
306*03ce13f7SAndroid Build Coastguard Worker 
307*03ce13f7SAndroid Build Coastguard Worker /// sys_write
env$$__syscall4(int Which,WasmArray<int> VarArgs)308*03ce13f7SAndroid Build Coastguard Worker int env$$__syscall4(int Which, WasmArray<int> VarArgs) {
309*03ce13f7SAndroid Build Coastguard Worker   TRACE_ENTRY();
310*03ce13f7SAndroid Build Coastguard Worker   int Fd = VarArgs[0];
311*03ce13f7SAndroid Build Coastguard Worker   int Buffer = VarArgs[1];
312*03ce13f7SAndroid Build Coastguard Worker   int Length = VarArgs[2];
313*03ce13f7SAndroid Build Coastguard Worker 
314*03ce13f7SAndroid Build Coastguard Worker   return trace(write(Fd, WASM_REF(char *, Buffer), Length));
315*03ce13f7SAndroid Build Coastguard Worker }
316*03ce13f7SAndroid Build Coastguard Worker 
317*03ce13f7SAndroid Build Coastguard Worker /// sys_open
env$$__syscall5(int Which,WasmArray<int> VarArgs)318*03ce13f7SAndroid Build Coastguard Worker int env$$__syscall5(int Which, WasmArray<int> VarArgs) {
319*03ce13f7SAndroid Build Coastguard Worker   TRACE_ENTRY();
320*03ce13f7SAndroid Build Coastguard Worker   int WasmPath = VarArgs[0];
321*03ce13f7SAndroid Build Coastguard Worker   int Flags = VarArgs[1];
322*03ce13f7SAndroid Build Coastguard Worker   int Mode = VarArgs[2];
323*03ce13f7SAndroid Build Coastguard Worker   const char *Path = WASM_REF(char, WasmPath);
324*03ce13f7SAndroid Build Coastguard Worker 
325*03ce13f7SAndroid Build Coastguard Worker   return trace(open(Path, Flags, Mode));
326*03ce13f7SAndroid Build Coastguard Worker }
327*03ce13f7SAndroid Build Coastguard Worker 
328*03ce13f7SAndroid Build Coastguard Worker /// sys_close
env$$__syscall6(int Which,WasmArray<int> VarArgs)329*03ce13f7SAndroid Build Coastguard Worker int env$$__syscall6(int Which, WasmArray<int> VarArgs) {
330*03ce13f7SAndroid Build Coastguard Worker   TRACE_ENTRY();
331*03ce13f7SAndroid Build Coastguard Worker   int Fd = VarArgs[0];
332*03ce13f7SAndroid Build Coastguard Worker 
333*03ce13f7SAndroid Build Coastguard Worker   return trace(close(Fd));
334*03ce13f7SAndroid Build Coastguard Worker }
335*03ce13f7SAndroid Build Coastguard Worker 
336*03ce13f7SAndroid Build Coastguard Worker /// sys_unlink
env$$__syscall10(int Which,WasmArray<int> VarArgs)337*03ce13f7SAndroid Build Coastguard Worker int env$$__syscall10(int Which, WasmArray<int> VarArgs) {
338*03ce13f7SAndroid Build Coastguard Worker   TRACE_ENTRY();
339*03ce13f7SAndroid Build Coastguard Worker   int WasmPath = VarArgs[0];
340*03ce13f7SAndroid Build Coastguard Worker   const char *Path = WASM_REF(char, WasmPath);
341*03ce13f7SAndroid Build Coastguard Worker 
342*03ce13f7SAndroid Build Coastguard Worker   return trace(unlink(Path));
343*03ce13f7SAndroid Build Coastguard Worker }
344*03ce13f7SAndroid Build Coastguard Worker 
345*03ce13f7SAndroid Build Coastguard Worker /// sys_getpid
env$$__syscall20(int Which,WasmArray<int> VarArgs)346*03ce13f7SAndroid Build Coastguard Worker int env$$__syscall20(int Which, WasmArray<int> VarArgs) {
347*03ce13f7SAndroid Build Coastguard Worker   TRACE_ENTRY();
348*03ce13f7SAndroid Build Coastguard Worker   (void)Which;
349*03ce13f7SAndroid Build Coastguard Worker   (void)VarArgs;
350*03ce13f7SAndroid Build Coastguard Worker 
351*03ce13f7SAndroid Build Coastguard Worker   return trace(getpid());
352*03ce13f7SAndroid Build Coastguard Worker }
353*03ce13f7SAndroid Build Coastguard Worker 
354*03ce13f7SAndroid Build Coastguard Worker /// sys_rmdir
env$$__syscall40(int Which,WasmArray<int> VarArgs)355*03ce13f7SAndroid Build Coastguard Worker int env$$__syscall40(int Which, WasmArray<int> VarArgs) {
356*03ce13f7SAndroid Build Coastguard Worker   TRACE_ENTRY();
357*03ce13f7SAndroid Build Coastguard Worker   int WasmPath = VarArgs[0];
358*03ce13f7SAndroid Build Coastguard Worker   const char *Path = WASM_REF(char, WasmPath);
359*03ce13f7SAndroid Build Coastguard Worker 
360*03ce13f7SAndroid Build Coastguard Worker   return trace(rmdir(Path));
361*03ce13f7SAndroid Build Coastguard Worker }
362*03ce13f7SAndroid Build Coastguard Worker 
363*03ce13f7SAndroid Build Coastguard Worker /// sys_ioctl
env$$__syscall54(int Which,WasmArray<int> VarArgs)364*03ce13f7SAndroid Build Coastguard Worker int env$$__syscall54(int Which, WasmArray<int> VarArgs) {
365*03ce13f7SAndroid Build Coastguard Worker   TRACE_ENTRY();
366*03ce13f7SAndroid Build Coastguard Worker   int Fd = VarArgs[0];
367*03ce13f7SAndroid Build Coastguard Worker   int Op = VarArgs[1];
368*03ce13f7SAndroid Build Coastguard Worker   int ArgP = VarArgs[2];
369*03ce13f7SAndroid Build Coastguard Worker 
370*03ce13f7SAndroid Build Coastguard Worker   switch (Op) {
371*03ce13f7SAndroid Build Coastguard Worker   case TCGETS: {
372*03ce13f7SAndroid Build Coastguard Worker     // struct termios has no pointers. Otherwise, we'd have to rewrite them.
373*03ce13f7SAndroid Build Coastguard Worker     struct termios *TermIOS = WASM_REF(struct termios, ArgP);
374*03ce13f7SAndroid Build Coastguard Worker     return trace(ioctl(Fd, TCGETS, TermIOS));
375*03ce13f7SAndroid Build Coastguard Worker   }
376*03ce13f7SAndroid Build Coastguard Worker   default:
377*03ce13f7SAndroid Build Coastguard Worker     // TODO (eholk): implement more ioctls
378*03ce13f7SAndroid Build Coastguard Worker     return trace(-ENOTTY);
379*03ce13f7SAndroid Build Coastguard Worker   }
380*03ce13f7SAndroid Build Coastguard Worker }
381*03ce13f7SAndroid Build Coastguard Worker 
382*03ce13f7SAndroid Build Coastguard Worker struct IoVec {
383*03ce13f7SAndroid Build Coastguard Worker   WasmPtr<char> Ptr;
384*03ce13f7SAndroid Build Coastguard Worker   int Length;
385*03ce13f7SAndroid Build Coastguard Worker };
386*03ce13f7SAndroid Build Coastguard Worker 
387*03ce13f7SAndroid Build Coastguard Worker /// sys_readv
env$$__syscall145(int Which,WasmArray<int> VarArgs)388*03ce13f7SAndroid Build Coastguard Worker int env$$__syscall145(int Which, WasmArray<int> VarArgs) {
389*03ce13f7SAndroid Build Coastguard Worker   TRACE_ENTRY();
390*03ce13f7SAndroid Build Coastguard Worker   int Fd = VarArgs[0];
391*03ce13f7SAndroid Build Coastguard Worker   WasmArray<IoVec> Iov = VarArgs[1];
392*03ce13f7SAndroid Build Coastguard Worker   int Iovcnt = VarArgs[2];
393*03ce13f7SAndroid Build Coastguard Worker 
394*03ce13f7SAndroid Build Coastguard Worker   int Count = 0;
395*03ce13f7SAndroid Build Coastguard Worker 
396*03ce13f7SAndroid Build Coastguard Worker   for (int I = 0; I < Iovcnt; ++I) {
397*03ce13f7SAndroid Build Coastguard Worker     int Curr = read(Fd, Iov[I].Ptr.asPtr(), Iov[I].Length);
398*03ce13f7SAndroid Build Coastguard Worker 
399*03ce13f7SAndroid Build Coastguard Worker     if (Curr < 0) {
400*03ce13f7SAndroid Build Coastguard Worker       return trace(-1);
401*03ce13f7SAndroid Build Coastguard Worker     }
402*03ce13f7SAndroid Build Coastguard Worker     Count += Curr;
403*03ce13f7SAndroid Build Coastguard Worker   }
404*03ce13f7SAndroid Build Coastguard Worker   return trace(Count);
405*03ce13f7SAndroid Build Coastguard Worker }
406*03ce13f7SAndroid Build Coastguard Worker 
407*03ce13f7SAndroid Build Coastguard Worker /// sys_writev
env$$__syscall146(int Which,WasmArray<int> VarArgs)408*03ce13f7SAndroid Build Coastguard Worker int env$$__syscall146(int Which, WasmArray<int> VarArgs) {
409*03ce13f7SAndroid Build Coastguard Worker   TRACE_ENTRY();
410*03ce13f7SAndroid Build Coastguard Worker   int Fd = VarArgs[0];
411*03ce13f7SAndroid Build Coastguard Worker   WasmArray<IoVec> Iov = VarArgs[1];
412*03ce13f7SAndroid Build Coastguard Worker   int Iovcnt = VarArgs[2];
413*03ce13f7SAndroid Build Coastguard Worker 
414*03ce13f7SAndroid Build Coastguard Worker   int Count = 0;
415*03ce13f7SAndroid Build Coastguard Worker 
416*03ce13f7SAndroid Build Coastguard Worker   for (int I = 0; I < Iovcnt; ++I) {
417*03ce13f7SAndroid Build Coastguard Worker     int Curr = write(Fd, Iov[I].Ptr.asPtr(), Iov[I].Length);
418*03ce13f7SAndroid Build Coastguard Worker 
419*03ce13f7SAndroid Build Coastguard Worker     if (Curr < 0) {
420*03ce13f7SAndroid Build Coastguard Worker       return trace(-1);
421*03ce13f7SAndroid Build Coastguard Worker     }
422*03ce13f7SAndroid Build Coastguard Worker     Count += Curr;
423*03ce13f7SAndroid Build Coastguard Worker   }
424*03ce13f7SAndroid Build Coastguard Worker   return trace(Count);
425*03ce13f7SAndroid Build Coastguard Worker }
426*03ce13f7SAndroid Build Coastguard Worker 
427*03ce13f7SAndroid Build Coastguard Worker /// sys_mmap_pgoff
env$$__syscall192(int Which,WasmArray<int> VarArgs)428*03ce13f7SAndroid Build Coastguard Worker int env$$__syscall192(int Which, WasmArray<int> VarArgs) {
429*03ce13f7SAndroid Build Coastguard Worker   TRACE_ENTRY();
430*03ce13f7SAndroid Build Coastguard Worker   (void)Which;
431*03ce13f7SAndroid Build Coastguard Worker   (void)VarArgs;
432*03ce13f7SAndroid Build Coastguard Worker 
433*03ce13f7SAndroid Build Coastguard Worker   // TODO (eholk): figure out how to implement this.
434*03ce13f7SAndroid Build Coastguard Worker 
435*03ce13f7SAndroid Build Coastguard Worker   return trace(-ENOMEM);
436*03ce13f7SAndroid Build Coastguard Worker }
437*03ce13f7SAndroid Build Coastguard Worker } // end of extern "C"
438