Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(191)

Unified Diff: runtime/wasm-runtime.cpp

Issue 1918213003: Subzero, Wasm: Dynamically reallocate read buffer. Runtime improvements. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Some code review feedback." Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: runtime/wasm-runtime.cpp
diff --git a/runtime/wasm-runtime.cpp b/runtime/wasm-runtime.cpp
index d867509ea51d1bf88a579f02d02232f3043b27dc..51b84b8bc0afe50a25cef35b03b4f7157b11cd20 100644
--- a/runtime/wasm-runtime.cpp
+++ b/runtime/wasm-runtime.cpp
@@ -14,8 +14,34 @@
#include <cassert>
#include <cmath>
John 2016/04/27 02:28:20 extreme nit ** 10: space between c++ and c headers
-// TODO (eholk): change to cstdint
+#include <errno.h>
+#include <fcntl.h>
+#include <iostream>
John 2016/04/27 02:28:20 move this to the "c++ header section?"
+#include <math.h>
#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <termios.h>
+#include <time.h>
+#include <unistd.h>
+
+#ifdef WASM_TRACE_RUNTIME
+#define TRACE_ENTRY() \
+ { std::cerr << __func__ << "(...) = "; }
+template <typename T> T trace(T x) {
+ std::cerr << x << std::endl;
+ return x;
+}
+void trace() { std::cerr << "(void)" << std::endl; }
+#else
+#define TRACE_ENTRY()
+template <typename T> T trace(T x) { return x; }
+void trace() {}
+#endif // WASM_TRACE_RUNTIME
namespace {
uint32_t HeapBreak;
@@ -35,16 +61,35 @@ float floor(float X) { return std::floor(X); }
} // end of namespace env
// TODO (eholk): move the C parts outside and use C++ name mangling.
+
+typedef int32_t WasmPtr;
+
+namespace {
+
+/// Some runtime functions need to return pointers. The WasmData struct is used
+/// to preallocate space for these on the heap.
+struct WasmData {
+
+ /// StrBuf is returned by functions that return strings.
+ char StrBuf[256];
+};
+
+WasmData *GlobalData = NULL;
+
+} // end of anonymous namespace
+
+// TODO (eholk): move the C parts outside and use C++ name mangling.
extern "C" {
-#include <errno.h>
-#include <fcntl.h>
-#include <math.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
+
+void __sz_bounds_fail() {
+ std::cerr << "Bounds check failure" << std::endl;
+ abort();
+}
+
+void __sz_indirect_fail() {
+ std::cerr << "Invalid indirect call target" << std::endl;
+ abort();
+}
extern char WASM_MEMORY[];
extern uint32_t WASM_DATA_SIZE;
@@ -57,11 +102,23 @@ void env$$abort() {
void env$$_abort() { env$$abort(); }
-double env$$floor_f(float X) { return env::floor(X); }
-double env$$floor_d(double X) { return env::floor(X); }
+double env$$floor_f(float X) {
+ TRACE_ENTRY();
+ return env::floor(X);
+}
+double env$$floor_d(double X) {
+ TRACE_ENTRY();
+ return env::floor(X);
+}
-void env$$exit(int Status) { exit(Status); }
-void env$$_exit(int Status) { env$$exit(Status); }
+void env$$exit(int Status) {
+ TRACE_ENTRY();
+ exit(Status);
+}
+void env$$_exit(int Status) {
+ TRACE_ENTRY();
+ env$$exit(Status);
+}
#define UNIMPLEMENTED(f) \
void env$$##f() { \
@@ -70,111 +127,248 @@ void env$$_exit(int Status) { env$$exit(Status); }
}
int32_t env$$sbrk(int32_t Increment) {
+ TRACE_ENTRY();
+ uint32_t OldBreak = HeapBreak;
HeapBreak += Increment;
- return HeapBreak;
+ return trace(OldBreak);
}
-UNIMPLEMENTED(setjmp)
-UNIMPLEMENTED(longjmp)
+UNIMPLEMENTED(__addtf3)
UNIMPLEMENTED(__assert_fail)
-UNIMPLEMENTED(__builtin_malloc)
-UNIMPLEMENTED(__builtin_isinff)
-UNIMPLEMENTED(__builtin_isinfl)
UNIMPLEMENTED(__builtin_apply)
UNIMPLEMENTED(__builtin_apply_args)
-UNIMPLEMENTED(pthread_cleanup_push)
-UNIMPLEMENTED(pthread_cleanup_pop)
-UNIMPLEMENTED(pthread_self)
-UNIMPLEMENTED(__floatditf)
-UNIMPLEMENTED(__floatsitf)
+UNIMPLEMENTED(__builtin_isinff)
+UNIMPLEMENTED(__builtin_isinfl)
+UNIMPLEMENTED(__builtin_malloc)
+UNIMPLEMENTED(__divtf3)
+UNIMPLEMENTED(__eqtf2)
+UNIMPLEMENTED(__extenddftf2)
+UNIMPLEMENTED(__extendsftf2)
+UNIMPLEMENTED(__fixsfti)
UNIMPLEMENTED(__fixtfdi)
UNIMPLEMENTED(__fixtfsi)
-UNIMPLEMENTED(__fixsfti)
-UNIMPLEMENTED(__netf2)
+UNIMPLEMENTED(__fixunstfsi)
+UNIMPLEMENTED(__floatditf)
+UNIMPLEMENTED(__floatsitf)
+UNIMPLEMENTED(__floatunsitf)
UNIMPLEMENTED(__getf2)
-UNIMPLEMENTED(__eqtf2)
+UNIMPLEMENTED(__letf2)
UNIMPLEMENTED(__lttf2)
-UNIMPLEMENTED(__addtf3)
-UNIMPLEMENTED(__subtf3)
-UNIMPLEMENTED(__divtf3)
UNIMPLEMENTED(__multf3)
UNIMPLEMENTED(__multi3)
-UNIMPLEMENTED(__lock)
-UNIMPLEMENTED(__unlock)
-UNIMPLEMENTED(__syscall6) // sys_close
+UNIMPLEMENTED(__netf2)
+UNIMPLEMENTED(__subtf3)
UNIMPLEMENTED(__syscall140) // sys_llseek
+UNIMPLEMENTED(__syscall221) // sys_fcntl64
+UNIMPLEMENTED(__trunctfdf2)
+UNIMPLEMENTED(__trunctfsf2)
UNIMPLEMENTED(__unordtf2)
-UNIMPLEMENTED(__fixunstfsi)
-UNIMPLEMENTED(__floatunsitf)
-UNIMPLEMENTED(__extenddftf2)
+UNIMPLEMENTED(longjmp)
+UNIMPLEMENTED(pthread_cleanup_pop)
+UNIMPLEMENTED(pthread_cleanup_push)
+UNIMPLEMENTED(pthread_self)
+UNIMPLEMENTED(setjmp)
-void *wasmPtr(uint32_t Index) {
+void *wasmPtr(int Index) {
if (pageNum(Index) < WASM_NUM_PAGES) {
return WASM_MEMORY + Index;
}
abort();
}
-extern int __szwasm_main(int, const char **);
+WasmPtr toWasm(void *Ptr) {
+ return reinterpret_cast<WasmPtr>(reinterpret_cast<char *>(Ptr) - WASM_MEMORY);
+}
+
+extern int __szwasm_main(int, WasmPtr);
#define WASM_REF(Type, Index) ((Type *)wasmPtr(Index))
#define WASM_DEREF(Type, Index) (*WASM_REF(Type, Index))
int main(int argc, const char **argv) {
+ // fprintf(stderr, "main(%d)\n", argc);
+
+ // TODO (eholk): align these allocations correctly.
+
+ // Allocate space for the global data.
+ HeapBreak = WASM_DATA_SIZE;
+ GlobalData = WASM_REF(WasmData, HeapBreak);
+ HeapBreak += sizeof(WasmData);
+
+ // copy the command line arguments.
+ WasmPtr WasmArgV = HeapBreak;
+ WasmPtr *WasmArgVPtr = WASM_REF(WasmPtr, WasmArgV);
+ HeapBreak += argc * sizeof(WasmPtr);
+
+ for (int i = 0; i < argc; ++i) {
+ WasmArgVPtr[i] = HeapBreak;
+ strcpy(WASM_REF(char, HeapBreak), argv[i]);
+ HeapBreak += strlen(argv[i]) + 1;
+ }
+
// Initialize the break to the nearest page boundary after the data segment
HeapBreak = (WASM_DATA_SIZE + PageSize - 1) & ~(PageSize - 1);
// Initialize the stack pointer.
WASM_DEREF(int32_t, StackPtrLoc) = WASM_NUM_PAGES << PageSizeLog2;
- return __szwasm_main(argc, argv);
+ return __szwasm_main(argc, WasmArgV);
}
-int env$$abs(int a) { return abs(a); }
+int env$$abs(int a) {
+ TRACE_ENTRY();
+ return trace(abs(a));
+}
-double env$$pow(double x, double y) { return pow(x, y); }
+clock_t env$$clock() {
+ TRACE_ENTRY();
+ return trace(clock());
+}
+
+WasmPtr env$$ctime(WasmPtr Time) {
+ TRACE_ENTRY();
+ time_t *TimePtr = WASM_REF(time_t, Time);
+ char *CTime = ctime(TimePtr);
+ strncpy(GlobalData->StrBuf, CTime, sizeof(GlobalData->StrBuf));
+ GlobalData->StrBuf[sizeof(GlobalData->StrBuf) - 1] = '\0';
+ return trace(toWasm(GlobalData->StrBuf));
+}
+
+double env$$pow(double x, double y) {
+ TRACE_ENTRY();
+ return trace(pow(x, y));
+}
+
+time_t env$$time(WasmPtr Time) {
+ TRACE_ENTRY();
+ time_t *TimePtr = WASM_REF(time_t, Time);
+ return trace(time(TimePtr));
+}
+
+// lock and unlock are no-ops in wasm.js, so we mimic that behavior.
+void env$$__lock(int32_t _) {
+ TRACE_ENTRY();
+ (void)_;
+ trace();
+}
+
+void env$$__unlock(int32_t _) {
+ TRACE_ENTRY();
+ (void)_;
+ trace();
+}
+
+/// sys_read
+int env$$__syscall3(int Which, int VarArgs) {
+ TRACE_ENTRY();
+ int Fd = WASM_DEREF(int, VarArgs + 0 * sizeof(int));
+ int Buffer = WASM_DEREF(int, VarArgs + 1 * sizeof(int));
+ int Length = WASM_DEREF(int, VarArgs + 2 * sizeof(int));
+
+ return trace(read(Fd, WASM_REF(char *, Buffer), Length));
+}
/// sys_write
int env$$__syscall4(int Which, int VarArgs) {
+ TRACE_ENTRY();
int Fd = WASM_DEREF(int, VarArgs + 0 * sizeof(int));
int Buffer = WASM_DEREF(int, VarArgs + 1 * sizeof(int));
int Length = WASM_DEREF(int, VarArgs + 2 * sizeof(int));
- return write(Fd, WASM_REF(char *, Buffer), Length);
+ return trace(write(Fd, WASM_REF(char *, Buffer), Length));
}
/// sys_open
int env$$__syscall5(int Which, int VarArgs) {
+ TRACE_ENTRY();
int WasmPath = WASM_DEREF(int, VarArgs);
int Flags = WASM_DEREF(int, VarArgs + 4);
int Mode = WASM_DEREF(int, VarArgs + 8);
const char *Path = WASM_REF(char, WasmPath);
- fprintf(stderr, "sys_open(%s, %d, %d)\n", Path, Flags, Mode);
+ return trace(open(Path, Flags, Mode));
+}
- return open(Path, Flags, Mode);
+/// sys_close
+int env$$__syscall6(int Which, int VarArgs) {
+ TRACE_ENTRY();
+ int Fd = WASM_DEREF(int, VarArgs + 0 * sizeof(int));
+
+ return trace(close(Fd));
+}
+
+/// sys_unlink
+int env$$__syscall10(int Which, int VarArgs) {
+ TRACE_ENTRY();
+ int WasmPath = WASM_DEREF(int, VarArgs);
+ const char *Path = WASM_REF(char, WasmPath);
+
+ return trace(unlink(Path));
}
/// sys_getpid
int env$$__syscall20(int Which, int VarArgs) {
+ TRACE_ENTRY();
(void)Which;
(void)VarArgs;
- return getpid();
+ return trace(getpid());
+}
+
+/// sys_rmdir
+int env$$__syscall40(int Which, int VarArgs) {
+ TRACE_ENTRY();
+ int WasmPath = WASM_DEREF(int, VarArgs);
+ const char *Path = WASM_REF(char, WasmPath);
+
+ return trace(rmdir(Path));
}
/// sys_ioctl
int env$$__syscall54(int A, int B) {
+ TRACE_ENTRY();
int Fd = WASM_DEREF(int, B + 0 * sizeof(int));
int Op = WASM_DEREF(int, B + 1 * sizeof(int));
int ArgP = WASM_DEREF(int, B + 2 * sizeof(int));
- // TODO (eholk): implement sys_ioctl
- return -ENOTTY;
+
+ switch (Op) {
+ case TCGETS: {
+ // struct termios has no pointers. Otherwise, we'd have to rewrite them.
+ struct termios *TermIOS = WASM_REF(struct termios, ArgP);
+ return trace(ioctl(Fd, TCGETS, TermIOS));
+ }
+ default:
+ // TODO (eholk): implement more ioctls
+ return trace(-ENOTTY);
+ }
}
-/// sys_write
-int env$$__syscall146(int Which, int VarArgs) {
+/// sys_readv
+int env$$__syscall145(int Which, int VarArgs) {
+ TRACE_ENTRY();
+ int Fd = WASM_DEREF(int, VarArgs);
+ int Iov = WASM_DEREF(int, VarArgs + sizeof(int));
+ int Iovcnt = WASM_DEREF(int, VarArgs + 2 * sizeof(int));
+
+ int Count = 0;
+
+ for (int I = 0; I < Iovcnt; ++I) {
+ void *Ptr = WASM_REF(void, WASM_DEREF(int, Iov + I * 8));
+ int Length = WASM_DEREF(int, Iov + I * 8 + 4);
+ int Curr = read(Fd, Ptr, Length);
+
+ if (Curr < 0) {
+ return trace(-1);
+ }
+ Count += Curr;
+ }
+ return trace(Count);
+}
+
+/// sys_writev
+int env$$__syscall146(int Which, int VarArgs) {
+ TRACE_ENTRY();
int Fd = WASM_DEREF(int, VarArgs);
int Iov = WASM_DEREF(int, VarArgs + sizeof(int));
int Iovcnt = WASM_DEREF(int, VarArgs + 2 * sizeof(int));
@@ -188,20 +382,21 @@ int env$$__syscall146(int Which, int VarArgs) {
int Curr = write(Fd, Ptr, Length);
if (Curr < 0) {
- return -1;
+ return trace(-1);
}
Count += Curr;
}
- return Count;
+ return trace(Count);
}
/// sys_mmap_pgoff
int env$$__syscall192(int Which, int VarArgs) {
+ TRACE_ENTRY();
(void)Which;
(void)VarArgs;
// TODO (eholk): figure out how to implement this.
- return -ENOMEM;
+ return trace(-ENOMEM);
}
} // end of extern "C"
« no previous file with comments | « pydir/wasm-run-torture-tests.py ('k') | src/IceCompiler.cpp » ('j') | src/IceCompiler.cpp » ('J')

Powered by Google App Engine
This is Rietveld 408576698