Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

the 60% #8

Merged
merged 1 commit into from
Dec 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 24 additions & 30 deletions src/common/function/FunctionManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,11 @@ std::unordered_map<std::string, std::vector<TypeSignature>> FunctionManager::typ
TypeSignature({Value::Type::STRING, Value::Type::STRING,Value::Type::STRING},
Value::Type::BOOL),
}},
{"delete_wasm", // wasm function,params([Function Name] [Function Handler] [Function Content(TODO://base64)])
{ // return BOOL
TypeSignature({Value::Type::STRING},
Value::Type::BOOL),
}},
};

// static
Expand Down Expand Up @@ -474,40 +479,28 @@ FunctionManager::FunctionManager() {
}
auto wasmFunctionName = args[0].get().getStr();
auto wasmFunctionHandler = args[1].get().getStr();
// auto watStr = args[2].get().getStr();

auto watStr = "(module\n"
" (func $gcd (param i32 i32) (result i32)\n"
" (local i32)\n"
" block ;; label = @1\n"
" block ;; label = @2\n"
" local.get 0\n"
" br_if 0 (;@2;)\n"
" local.get 1\n"
" local.set 2\n"
" br 1 (;@1;)\n"
" end\n"
" loop ;; label = @2\n"
" local.get 1\n"
" local.get 0\n"
" local.tee 2\n"
" i32.rem_u\n"
" local.set 0\n"
" local.get 2\n"
" local.set 1\n"
" local.get 0\n"
" br_if 0 (;@2;)\n"
" end\n"
" end\n"
" local.get 2\n"
" )\n"
" (export \"main\" (func $gcd))\n"
")";
auto watStr = args[2].get().getStr();
WasmFunctionManager& wasmFunctionManager = WasmFunctionManager::getInstance();
wasmFunctionManager.RegisterFunction(wasmFunctionName,wasmFunctionHandler,watStr);
return true;
};
}
{
auto &attr = functions_["delete_wasm"];
attr.minArity_ = 1;
attr.maxArity_ = 2;
attr.isPure_ = false;
// begin wasm call
attr.body_ = [](const auto &args) -> Value {
if (!args[0].get().isStr()) {
return Value::kNullBadType;
}
auto wasmFunctionName = args[0].get().getStr();
WasmFunctionManager& wasmFunctionManager = WasmFunctionManager::getInstance();
wasmFunctionManager.DeleteFunction(wasmFunctionName);
return true;
};
}
{
auto &attr = functions_["wasm"];
attr.minArity_ = 1;
Expand All @@ -521,7 +514,8 @@ FunctionManager::FunctionManager() {
auto wasmFunctionName = args[0].get().getStr();
auto &params = args[1].get().getList();
WasmFunctionManager& wasmFunctionManager = WasmFunctionManager::getInstance();
auto wasmRuntimeResult = wasmFunctionManager.runWithHandle(wasmFunctionName,params);
auto wasmRuntimeResult =
wasmFunctionManager.runWithNebulaDataHandle(wasmFunctionName, params);
return wasmRuntimeResult;
};
}
Expand Down
30 changes: 23 additions & 7 deletions src/common/function/WasmFunctionManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,26 +32,26 @@ std::string readFile(const std::string name) {
// std::cout << "gcd(6, 27) = " << results[0].i32() << "\n";
//}

WasmRuntime WasmFunctionManager::createInstanceAndFunction(const std::string &watString,
WasmtimeRunInstance WasmFunctionManager::createInstanceAndFunction(const std::string &watString,
const std::string functionHandler) {
auto module = wasmtime::Module::compile(*engine, watString).unwrap();
auto instance = wasmtime::Instance::create(store, module, {}).unwrap();

auto function_obj = instance.get(store, functionHandler);

wasmtime::Func *func = std::get_if<wasmtime::Func>(&*function_obj);
return WasmRuntime(*func, instance);
return WasmtimeRunInstance(*func, instance);
}

nebula::List WasmFunctionManager::runWithHandle(std::string functionName, nebula::List args) {
nebula::List WasmFunctionManager::runWithNebulaDataHandle(std::string functionName, nebula::List args) {

if(modules.find(functionName) == modules.end()){
// return not found!
std::vector<nebula::Value> Error;
Error.emplace_back("Not Found Function");
return nebula::List(Error);
}
auto value = modules.at(functionName);
auto module = modules.at(functionName);
// prepostcess
auto values = args.values;
std::vector<int> functionArgs;
Expand All @@ -60,7 +60,7 @@ nebula::List WasmFunctionManager::runWithHandle(std::string functionName, nebula
functionArgs.push_back(val.getInt());
}
// run
auto functionResult = WasmFunctionManager::run(value, functionArgs);
auto functionResult = WasmFunctionManager::run(module, functionArgs);

// postprocess
std::vector<nebula::Value> tmpProcess;
Expand All @@ -69,7 +69,17 @@ nebula::List WasmFunctionManager::runWithHandle(std::string functionName, nebula
}
return nebula::List(tmpProcess);
}
std::vector<int> WasmFunctionManager::run(const WasmRuntime &wasmRuntime, std::vector<int> args) {

std::vector<int> WasmFunctionManager::run(std::string functionName, std::vector<int> args) {
if(modules.find(functionName) == modules.end()){
return std::vector<int>();
}
auto module = modules.at(functionName);
// run
return WasmFunctionManager::run(module, args);

}
std::vector<int> WasmFunctionManager::run(const WasmtimeRunInstance &wasmRuntime, std::vector<int> args) {
// the args which wasm run

std::vector<wasmtime::Val> argv;
Expand All @@ -88,11 +98,17 @@ std::vector<int> WasmFunctionManager::run(const WasmRuntime &wasmRuntime, std::v
return result;
}

bool WasmFunctionManager::RegisterFunction(std::string functionName,std::string functionHandler,const std::string &watString) {
bool WasmFunctionManager::RegisterFunction(std::string functionName,std::string functionHandler,const std::string &watBase64String) {
// default functionHandler = "main"
auto watString = myBase64Decode(watBase64String);
auto wasmRuntime = createInstanceAndFunction(watString,functionHandler);
modules.emplace(functionName,wasmRuntime);
return true;
}

bool WasmFunctionManager::DeleteFunction(std::string functionName) {
modules.erase(functionName);
return true;
}

} // namespace nebula
98 changes: 91 additions & 7 deletions src/common/function/WasmFunctionManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,20 @@
#define NEBULA_GRAPH_WASMFUNCTIONMANAGER_H
#include "common/datatypes/Value.h"
#include "common/function/FunctionManager.h"
#include <string>
#include <cassert>
#include <limits>
#include <stdexcept>
#include <cctype>
#include <wasmtime.hh>


namespace nebula {

struct WasmRuntime {
struct WasmtimeRunInstance {
wasmtime::Func func;
wasmtime::Instance instance;
WasmRuntime(const wasmtime::Func &func, const wasmtime::Instance &instance)
WasmtimeRunInstance(const wasmtime::Func &func, const wasmtime::Instance &instance)
: func(func), instance(instance) {}
};

Expand All @@ -23,7 +28,7 @@ class WasmFunctionManager {
wasmtime::Engine *engine;
wasmtime::Store *store;
/* data */
std::unordered_map<std::string, WasmRuntime> modules;
std::unordered_map<std::string, WasmtimeRunInstance> modules;
WasmFunctionManager() {
engine = new wasmtime::Engine;
store = new wasmtime::Store(*engine);
Expand All @@ -35,6 +40,20 @@ class WasmFunctionManager {
}
WasmFunctionManager(const WasmFunctionManager&);
WasmFunctionManager& operator=(const WasmFunctionManager&);

// base64 tool
constexpr static const char b64_table[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

constexpr static const char reverse_table[128] = {
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64,
64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64,
64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64
};
public:
// static WasmFunctionManager& getInstance() {
// static WasmFunctionManager instance;
Expand All @@ -54,13 +73,78 @@ class WasmFunctionManager {

void runWat(const std::string &watString) const;

WasmRuntime createInstanceAndFunction(const std::string &watString,
WasmtimeRunInstance createInstanceAndFunction(const std::string &watString,
const std::string functionHandler);
std::vector<int> run(const WasmRuntime &wasmRuntime, std::vector<int> args);
std::vector<int> run(const WasmtimeRunInstance &wasmRuntime, std::vector<int> args);
bool RegisterFunction(std::string functionName,
std::string functionHandler,
const std::string &watString);
List runWithHandle(std::string functionName, List args);
const std::string &watBase64String);
bool DeleteFunction(std::string functionName);
List runWithNebulaDataHandle(std::string functionName, List args);
std::vector<int> run(std::string functionName, std::vector<int> args);

// base64 tool
static std::string myBase64Encode(const ::std::string &bindata)
{
using ::std::string;
using ::std::numeric_limits;

if (bindata.size() > (numeric_limits<string::size_type>::max() / 4u) * 3u) {
throw ::std::length_error("Converting too large a string to base64.");
}

const ::std::size_t binlen = bindata.size();
// Use = signs so the end is properly padded.
string retval((((binlen + 2) / 3) * 4), '=');
::std::size_t outpos = 0;
int bits_collected = 0;
unsigned int accumulator = 0;
const string::const_iterator binend = bindata.end();

for (string::const_iterator i = bindata.begin(); i != binend; ++i) {
accumulator = (accumulator << 8) | (*i & 0xffu);
bits_collected += 8;
while (bits_collected >= 6) {
bits_collected -= 6;
retval[outpos++] = b64_table[(accumulator >> bits_collected) & 0x3fu];
}
}
if (bits_collected > 0) { // Any trailing bits that are missing.
assert(bits_collected < 6);
accumulator <<= 6 - bits_collected;
retval[outpos++] = b64_table[accumulator & 0x3fu];
}
assert(outpos >= (retval.size() - 2));
assert(outpos <= retval.size());
return retval;
}

static std::string myBase64Decode(const ::std::string &ascdata)
{
using ::std::string;
string retval;
const string::const_iterator last = ascdata.end();
int bits_collected = 0;
unsigned int accumulator = 0;

for (string::const_iterator i = ascdata.begin(); i != last; ++i) {
const int c = *i;
if (::std::isspace(c) || c == '=') {
// Skip whitespace and padding. Be liberal in what you accept.
continue;
}
if ((c > 127) || (c < 0) || (reverse_table[c] > 63)) {
throw ::std::invalid_argument("This contains characters not legal in a base64 encoded string.");
}
accumulator = (accumulator << 6) | reverse_table[c];
bits_collected += 6;
if (bits_collected >= 8) {
bits_collected -= 8;
retval += static_cast<char>((accumulator >> bits_collected) & 0xffu);
}
}
return retval;
}
};
} // namespace nebula

Expand Down
60 changes: 31 additions & 29 deletions src/common/function/test/WasmFunctionManagerTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,36 +7,38 @@
namespace nebula {
namespace graph {
TEST(WasmFunctionTest, gen) {
auto WatStr = "(module\n"
" (func $gcd (param i32 i32) (result i32)\n"
" (local i32)\n"
" block ;; label = @1\n"
" block ;; label = @2\n"
" local.get 0\n"
" br_if 0 (;@2;)\n"
" local.get 1\n"
" local.set 2\n"
" br 1 (;@1;)\n"
" end\n"
" loop ;; label = @2\n"
" local.get 1\n"
" local.get 0\n"
" local.tee 2\n"
" i32.rem_u\n"
" local.set 0\n"
" local.get 2\n"
" local.set 1\n"
" local.get 0\n"
" br_if 0 (;@2;)\n"
" end\n"
" end\n"
" local.get 2\n"
" )\n"
" (export \"main\" (func $gcd))\n"
")";

auto wasmRuntime = WasmFunctionManager::createInstanceAndFunction(WatStr,"main");
auto result = WasmFunctionManager::run(wasmRuntime,{6, 27});
// auto watStr = "(module\n"
// " (func $gcd (param i32 i32) (result i32)\n"
// " (local i32)\n"
// " block ;; label = @1\n"
// " block ;; label = @2\n"
// " local.get 0\n"
// " br_if 0 (;@2;)\n"
// " local.get 1\n"
// " local.set 2\n"
// " br 1 (;@1;)\n"
// " end\n"
// " loop ;; label = @2\n"
// " local.get 1\n"
// " local.get 0\n"
// " local.tee 2\n"
// " i32.rem_u\n"
// " local.set 0\n"
// " local.get 2\n"
// " local.set 1\n"
// " local.get 0\n"
// " br_if 0 (;@2;)\n"
// " end\n"
// " end\n"
// " local.get 2\n"
// " )\n"
// " (export \"main\" (func $gcd))\n"
// ")";
auto WatBase64Str = "KG1vZHVsZQogIChmdW5jICRnY2QgKHBhcmFtIGkzMiBpMzIpIChyZXN1bHQgaTMyKQogICAgKGxvY2FsIGkzMikKICAgIGJsb2NrICA7OyBsYWJlbCA9IEAxCiAgICAgIGJsb2NrICA7OyBsYWJlbCA9IEAyCiAgICAgICAgbG9jYWwuZ2V0IDAKICAgICAgICBicl9pZiAwICg7QDI7KQogICAgICAgIGxvY2FsLmdldCAxCiAgICAgICAgbG9jYWwuc2V0IDIKICAgICAgICBiciAxICg7QDE7KQogICAgICBlbmQKICAgICAgbG9vcCAgOzsgbGFiZWwgPSBAMgogICAgICAgIGxvY2FsLmdldCAxCiAgICAgICAgbG9jYWwuZ2V0IDAKICAgICAgICBsb2NhbC50ZWUgMgogICAgICAgIGkzMi5yZW1fdQogICAgICAgIGxvY2FsLnNldCAwCiAgICAgICAgbG9jYWwuZ2V0IDIKICAgICAgICBsb2NhbC5zZXQgMQogICAgICAgIGxvY2FsLmdldCAwCiAgICAgICAgYnJfaWYgMCAoO0AyOykKICAgICAgZW5kCiAgICBlbmQKICAgIGxvY2FsLmdldCAyCiAgKQogIChleHBvcnQgIm1haW4iIChmdW5jICRnY2QpKSA7OyBleHBvcnQgd2l0aCBtYWluCikK";
WasmFunctionManager& wasmFunctionManager = WasmFunctionManager::getInstance();
wasmFunctionManager.RegisterFunction("gcd","main",WatBase64Str);
auto result = wasmFunctionManager.run("gcd",{6, 27});
std::cout << result[0] << "\n";
} // namespace graph
}}