Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
xiaoxiaojx committed Oct 3, 2023
1 parent 1f3acce commit 0e4518b
Show file tree
Hide file tree
Showing 13 changed files with 260 additions and 106 deletions.
12 changes: 12 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
CMakeFiles/
cmake_install.cmake
CmakeCache.txt
Makefile
install_manifest.txt
googletest*/
.DS_Store
node_modules/
*.dSYM/
*.a
/build*
wvm
4 changes: 3 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
run:
make build && ./wvm ./hello-world.wasm
make build && make start
start:
./wvm ./hello-world.wasm
build:
g++ src/*.cc -o wvm -pthread -std=c++17
9 changes: 0 additions & 9 deletions src/constants.h

This file was deleted.

15 changes: 11 additions & 4 deletions src/decoder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ namespace wvm
return readable_;
}

std::vector<char> Decoder::readBytes(char n)
std::vector<uint8_t> Decoder::readBytes(uint8_t n)
{
std::vector<char> buffer(n); // 创建一个存储字节的缓冲区
readable_.read(buffer.data(), n); // 从文件流中读取 n 个字节到缓冲区
std::vector<uint8_t> buffer(n); // 创建一个存储字节的缓冲区
readable_.read(reinterpret_cast<char *>(buffer.data()), n); // 从文件流中读取 n 个字节到缓冲区

// 如果未能读取足够的字节,可以根据需要进行处理(例如抛出异常)
if (readable_.gcount() < static_cast<std::streamsize>(n))
Expand All @@ -31,11 +31,18 @@ namespace wvm
// 可以在这里抛出异常或者进行其他错误处理操作
}

return buffer; // 返回读取到的字节数据P
return buffer; // 返回读取到的字节数据
}

uint8_t Decoder::readByte()
{
return static_cast<uint8_t>(readable_.get());
}

std::string Decoder::readStringByBytes(size_t n)
{
char str[n];
readable_.read(str, n);
return std::string(str, n);
}
}
7 changes: 4 additions & 3 deletions src/decoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@ namespace wvm
~Decoder();

std::ifstream &readable();
std::vector<char> readBytes(char n);

std::vector<uint8_t> readBytes(uint8_t n);
uint8_t readByte();
std::string readStringByBytes(size_t n);

template <typename U>
static std::vector<uint8_t> retrievePackedLEB128Bytes(U &&in)
Expand Down Expand Up @@ -99,9 +100,9 @@ namespace wvm
return val;
}

#define WALK_FUNC_DEF(name, type, suffix) \
#define WALK_FUNC_DEF(name, type, suffix) \
type read##name() \
{ \
{ \
return decodeVar##suffix<type>(readable_); \
}

Expand Down
12 changes: 12 additions & 0 deletions src/instance.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#include "instance.h"

namespace wvm
{
Instance::Instance()
{
}

Instance::~Instance()
{
}
}
14 changes: 14 additions & 0 deletions src/instance.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#ifndef SRC_INSTANCE_H_
#define SRC_INSTANCE_H_

namespace wvm
{
class Instance
{
public:
Instance();
~Instance();
};
}

#endif // SRC_INSTANCE_H_
10 changes: 0 additions & 10 deletions src/log.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,6 @@

#include <iostream>

// 重载输出运算符以支持 std::vector<char> 类型的输出
std::ostream &operator<<(std::ostream &os, const std::vector<char> &vec)
{
for (const auto &ch : vec)
{
os << ch;
}
return os;
}

#define LOG(...) std::cout << "[WVM]: " << (__VA_ARGS__) << std::endl

#endif // SRC_LOG_H_
158 changes: 130 additions & 28 deletions src/module.cc
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@

#include "module.h"
#include "log.h"
#include "constants.h"

namespace wvm
{
Expand All @@ -18,7 +17,7 @@ namespace wvm
return decoder_;
}

bool Module::byteArrayEq(const std::vector<char> &input1, const std::vector<char> &input2)
bool Module::byteArrayEq(const std::vector<uint8_t> &input1, const std::vector<uint8_t> &input2)
{
if (input1.size() != input2.size())
{
Expand All @@ -38,9 +37,7 @@ namespace wvm

void Module::parseMagicNumber()
{
std::vector<char> buffer = decoder_->readBytes(4);
LOG("parseMagicNumber -> ", buffer);

std::vector<uint8_t> buffer = decoder_->readBytes(4);
if (!byteArrayEq(MAGIC_NUMBER, buffer))
{
LOG("magic header not detected");
Expand All @@ -50,9 +47,7 @@ namespace wvm

void Module::parseVersion()
{
std::vector<char> buffer = decoder_->readBytes(4);
LOG("parseVersion -> ", buffer);

std::vector<uint8_t> buffer = decoder_->readBytes(4);
if (!byteArrayEq(WASM_VERSION, buffer))
{
LOG("unknown binary version");
Expand All @@ -62,28 +57,59 @@ namespace wvm

void Module::parseSection()
{
Section sectionId = static_cast<Section>(decoder_->readByte());

switch (sectionId)
LOG("parseSection start");
while (!decoder_->readable().eof())
{
case Section::type:
/* code */
LOG("parseTypeSection");
parseTypeSection();
break;
case Section::import:
/* code */
LOG("parseImportSection");
parseImportSection();
break;
case Section::func:
/* code */
LOG("parseFunctionSection");
parseFunctionSection();
break;
default:
break;
Section sectionId = static_cast<Section>(decoder_->readByte());
std::cout << "sectionId: " << static_cast<int>(sectionId) << std::endl;

switch (sectionId)
{
case Section::type:
/* Type section -> https://webassembly.github.io/spec/core/binary/modules.html#binary-typesec */
parseTypeSection();
break;
case Section::import:
/* Import section -> https://webassembly.github.io/spec/core/binary/modules.html#binary-importsec */
parseImportSection();
break;
case Section::func:
/* Function section -> https://webassembly.github.io/spec/core/binary/modules.html#function-section */
LOG("parseFunctionSection");
parseFunctionSection();
break;
case Section::table:
/* Table section -> https://webassembly.github.io/spec/core/binary/modules.html#table-section */
LOG("parseTableSection");
parseTableSection();
break;
case Section::memory:
/* Memory section -> https://webassembly.github.io/spec/core/binary/modules.html#memory-section */
LOG("parseMemorySection");
parseMemorySection();
break;
case Section::global:
/* Global section -> https://webassembly.github.io/spec/core/binary/modules.html#global-section */
LOG("parseGlobalSection");
parseGlobalSection();

case Section::export_section:
/* Export section -> https://webassembly.github.io/spec/core/binary/modules.html#export-section */
LOG("parseExportSection");
parseExportSection();
break;

case Section::code:
/* Code section -> https://webassembly.github.io/spec/core/binary/modules.html#binary-codesec */
LOG("parseCodeSection");
parseCodeSection();
break;
default:
break;
}
}
LOG("parseSection end");
decoder_->readable().close();
}
// ; func type 0
// 000000b: 60 ; func
Expand Down Expand Up @@ -151,4 +177,80 @@ namespace wvm
void Module::parseMemorySection()
{
}

void Module::parseGlobalSection()
{
}

// ; section "Export" (7)
// 0000016: 07 ; section code
// 0000017: 00 ; section size (guess)
// 0000018: 01 ; num exports
// 0000019: 03 ; string length
// 000001a: 6164 64 add ; export name
// 000001d: 00 ; export kind
// 000001e: 00 ; export func index
// 0000017: 07 ; FIXUP section size
void Module::parseExportSection()
{
WVM_KEEPALIVE const auto sectionSize = decoder_->readU32();
const auto exportCount = decoder_->readU32();
for (uint32_t i = 0; i < exportCount; ++i)
{
const auto fieldLen = decoder_->readU32();
const auto fieldStr = decoder_->readStringByBytes(fieldLen);
const auto extKind = decoder_->readByte();
const auto extIdx = decoder_->readU32();
exports.emplace_back(fieldStr, extKind, extIdx);
}
}
// ; section "Code" (10)
// 000001f: 0a ; section code
// 0000020: 00 ; section size (guess)
// 0000021: 02 ; num functions
// ; function body 0
// 0000022: 00 ; func body size (guess)
// 0000023: 00 ; local decl count
// 0000024: 20 ; local.get
// 0000025: 00 ; local index
// 0000026: 20 ; local.get
// 0000027: 01 ; local index
// 0000028: 10 ; call
// 0000029: 01 ; function index
// 000002a: 0b ; end
// 0000022: 08 ; FIXUP func body size
// ; function body 1
// 000002b: 00 ; func body size (guess)
// 000002c: 00 ; local decl count
// 000002d: 20 ; local.get
// 000002e: 00 ; local index
// 000002f: 20 ; local.get
// 0000030: 01 ; local index
// 0000031: 41 ; i32.const
// 0000032: 0a ; i32 literal
// 0000033: 1a ; drop
// 0000034: 6a ; i32.add
// 0000035: 0b ; end
// 000002b: 0a ; FIXUP func body size
// 0000020: 15 ; FIXUP section size
void Module::parseCodeSection()
{
WVM_KEEPALIVE const auto sectionSize = decoder_->readU32();
const auto funcDefCount = decoder_->readU32();
for (uint32_t i = 0; i < funcDefCount; ++i)
{
const auto bodySize = decoder_->readU32();
const auto startPos = decoder_->readable().tellg();
const auto locCount = decoder_->readU32();
std::vector<uint8_t> locVarTypeVec = {};
for (uint32_t j = 0; j < locCount; ++j)
{
const auto locVarCount = decoder_->readU32();
const auto locVarType = decoder_->readByte();
locVarTypeVec.insert(locVarTypeVec.end(), locVarCount, locVarType);
}
std::vector<uint8_t> body = decoder_->readBytes(bodySize - (decoder_->readable().tellg() - startPos));
funcDefs.emplace_back(locVarTypeVec, body);
}
}
}
Loading

0 comments on commit 0e4518b

Please sign in to comment.