Skip to content

Commit

Permalink
feature: 对接http server与sysy编译器
Browse files Browse the repository at this point in the history
  • Loading branch information
Kingtous committed Mar 18, 2021
1 parent d9a2dac commit a0b6e5c
Show file tree
Hide file tree
Showing 10 changed files with 150 additions and 117 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ add_executable(sysyplus_compiler
)

# CGUI存在则生成可视化界面 DEBUG_FLAG开启调试模式
add_compile_definitions(sysyplus_compiler PUBLIC CGUI=1 DEBUG_FLAG=1)
add_compile_definitions(sysyplus_compiler PUBLIC DEBUG_FLAG=1)

# Find the libraries that correspond to the LLVM components
# that we wish to use
Expand Down
14 changes: 9 additions & 5 deletions ast/NodeAST.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ llvm::Value *CallExprAST::codegen() {
Value *av = args[i]->codegen();
if (av == NIL) {
ABORT_COMPILE;
return LogErrorV(("函数形参解析失败:" + av->getName()).str().c_str());
return LogErrorV(("函数形参解析失败:" + args[i]->toString()).c_str());
}
argsV.push_back(av);
}
Expand Down Expand Up @@ -508,9 +508,9 @@ llvm::Function *FunctionAST::codegen() {
LogError(("function '" + Proto->getName() + "' not valid\n").c_str());
errs() << "function ll codes:\n";
function->print(errs());
ABORT_COMPILE;
goto clean;
} else {
ABORT_COMPILE;
cleanCodeGenContext();
}
return function;
Expand Down Expand Up @@ -705,10 +705,14 @@ llvm::Value *IdentifierExprAST::codegen() {
auto gv = TheModule->getNamedGlobal(identifier);
if (gv) {
return Builder->CreateLoad(gv);
} else {
ABORT_COMPILE;
return LogErrorV((identifier + " is not defined!!!").c_str());
}
// 可能是函数指针
auto func = TheModule->getFunction(identifier);
if (func != NIL){
return func;
}
ABORT_COMPILE;
return LogErrorV((identifier + " is not defined!!!").c_str());
}

IdentifierExprAST::IdentifierExprAST() {
Expand Down
76 changes: 66 additions & 10 deletions extern/ExternFunctionHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ EchoFunctionHandler::tryhandle(LLVMContext &context, Module &module, std::string
auto symbol_mem = Builder->CreateAlloca(symbol_value->getType());
Builder->CreateStore(symbol_value, symbol_mem);
auto symbol_pointer = Builder->CreateInBoundsGEP(symbol_mem,
{ConstantInt::get(Type::getInt32Ty(context), 0),
ConstantInt::get(Type::getInt32Ty(context), 0)});
{ConstantInt::get(Type::getInt32Ty(context), 0),
ConstantInt::get(Type::getInt32Ty(context), 0)});
argV->insert(argV->begin(), symbol_pointer);
return Builder->CreateCall(getOrAddPrintfFunc(context, module), *argV, "echo");
}
Expand Down Expand Up @@ -196,8 +196,11 @@ Function *ExternFunctionHandler::getOrAddGetRequestFunc(LLVMContext &context, Mo
return func;
}
FunctionType *ty = FunctionType::get(Type::getInt8Ty(context)->getPointerTo(), {Type::getInt32Ty(context),
Type::getInt8Ty(context)->getPointerTo(),
Type::getInt8Ty(context)->getPointerTo()}, false);
Type::getInt8Ty(
context)->getPointerTo(),
Type::getInt8Ty(
context)->getPointerTo()},
false);
func = Function::Create(ty, llvm::GlobalValue::ExternalLinkage, "_web_callGetRequest", module);
return func;
}
Expand All @@ -208,13 +211,57 @@ Function *ExternFunctionHandler::getOrAddPostRequestFunc(LLVMContext &context, M
return func;
}
FunctionType *ty = FunctionType::get(Type::getInt8Ty(context)->getPointerTo(), {Type::getInt32Ty(context),
Type::getInt8Ty(context)->getPointerTo(),
Type::getInt8Ty(context)->getPointerTo(),
Type::getInt8Ty(context)->getPointerTo()}, false);
Type::getInt8Ty(
context)->getPointerTo(),
Type::getInt8Ty(
context)->getPointerTo(),
Type::getInt8Ty(
context)->getPointerTo()},
false);
func = Function::Create(ty, llvm::GlobalValue::ExternalLinkage, "_web_callPostRequest", module);
return func;
}

Function *ExternFunctionHandler::getOrAddGetServerFunc(LLVMContext &context, Module &module) {
Function *func = module.getFunction("_web_getServerId");
if (func != NIL) {
return func;
}
FunctionType *ty = FunctionType::get(Type::getInt32Ty(context),
{Type::getInt8PtrTy(context),
Type::getInt32Ty(context),
Type::getInt32Ty(context)}, false);
func = Function::Create(ty, llvm::GlobalValue::ExternalLinkage, "_web_getServerId", module);
return func;
}

Function *ExternFunctionHandler::getOrAddUrlHandler(LLVMContext &context, Module &module) {
Function *func = module.getFunction("_web_addUrlHandler");
if (func != NIL) {
return func;
}
auto func_param_type = FunctionType::get(Type::getInt8PtrTy(context),false);

FunctionType *ty = FunctionType::get(Type::getInt32Ty(context),
{Type::getInt32Ty(context),
Type::getInt8Ty(context)->getPointerTo(),
Type::getInt8Ty(context)->getPointerTo(),
func_param_type->getPointerTo()}, false);
func = Function::Create(ty, llvm::GlobalValue::ExternalLinkage, "_web_addUrlHandler", module);
return func;
}

Function *ExternFunctionHandler::getOrAddStartServer(LLVMContext &context, Module &module) {
Function *func = module.getFunction("_web_startServe");
if (func != NIL) {
return func;
}
FunctionType *ty = FunctionType::get(Type::getInt32Ty(context),
Type::getInt32Ty(context), false);
func = Function::Create(ty, llvm::GlobalValue::ExternalLinkage, "_web_startServe", module);
return func;
}

Value *
WebFunctionHandler::tryhandle(LLVMContext &context, Module &module, std::string callName, std::vector<Value *> *argV) {
// 处理 {@link module/web/web.h},注意名字要保持一致
Expand All @@ -230,12 +277,21 @@ WebFunctionHandler::tryhandle(LLVMContext &context, Module &module, std::string
} else if (callName == "getRequest" && !argV->empty()) {
auto func = ExternFunctionHandler::getOrAddGetRequestFunc(context, module);
return Builder->CreateCall(func, *argV);
} else if (callName == "isSocketConnected" && !argV->empty()){
auto func = ExternFunctionHandler::getOrAddIsSocketConnectedFunc(context,module);
return Builder->CreateCall(func,*argV);
} else if (callName == "isSocketConnected" && !argV->empty()) {
auto func = ExternFunctionHandler::getOrAddIsSocketConnectedFunc(context, module);
return Builder->CreateCall(func, *argV);
} else if (callName == "postRequest" && !argV->empty()) {
auto func = ExternFunctionHandler::getOrAddPostRequestFunc(context, module);
return Builder->CreateCall(func, *argV);
} else if (callName == "getServer" && !argV->empty()) {
auto func = ExternFunctionHandler::getOrAddGetServerFunc(context, module);
return Builder->CreateCall(func, *argV);
} else if (callName == "addUrlHandler" && !argV->empty()) {
auto func = ExternFunctionHandler::getOrAddUrlHandler(context, module);
return Builder->CreateCall(func, *argV);
} else if (callName == "startServer" && !argV->empty()) {
auto func = ExternFunctionHandler::getOrAddStartServer(context, module);
return Builder->CreateCall(func, *argV);
}
return NIL;
}
Expand Down
6 changes: 6 additions & 0 deletions extern/ExternFunctionHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ class ExternFunctionHandler {
static Function *getOrAddGetRequestFunc(LLVMContext &context, Module &module);

static Function *getOrAddPostRequestFunc(LLVMContext &context, Module &module);

static Function *getOrAddGetServerFunc(LLVMContext &context, Module &module);

static Function *getOrAddUrlHandler(LLVMContext &context, Module &module);

static Function *getOrAddStartServer(LLVMContext &context, Module &module);
};


Expand Down
32 changes: 3 additions & 29 deletions module/web/src/serverdemo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,35 +14,9 @@ const char *say_hi() {


void startServer() {
auto const address = boost::asio::ip::make_address("127.0.0.1");
unsigned short port = 9000;
std::string root = "~/";

auto handler1 = new WebHttpHandler();
auto handler2 = new WebHttpHandler();

handler1->path = new std::string("/hello");
handler2->path = new std::string("/hi");

handler1->method = new std::string("GET");
handler2->method = new std::string("POST");

handler1->function = say_hello;
handler2->function = say_hi;

boost::asio::io_context ioc{1};
tcp::acceptor acceptor{ioc, {address, port}};
_web_HttpWorker httpWorker1(acceptor, root);
_web_HttpWorker httpWorker2(acceptor, root);

httpWorker1.addHandler(*handler1);
httpWorker1.addHandler(*handler2);
httpWorker2.addHandler(*handler1);
httpWorker2.addHandler(*handler2);

httpWorker1.start();
httpWorker2.start();
ioc.run();
int id = _web_getServerId("127.0.0.1",9000,2);
_web_addUrlHandler(id,"POST","/compiler",say_hi);
_web_startServe(id);
}


Expand Down
15 changes: 8 additions & 7 deletions module/web/src/web.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "web.hpp"

boost::asio::io_context *_web_io_context = nullptr;
boost::asio::io_context *_server_context = nullptr;
tcp::resolver *_web_resolver = nullptr;
map<int, tcp::socket *> _web_tcp_socket_map;
map<int, std::vector<_web_HttpWorker *>> _web_http_server_map;
Expand Down Expand Up @@ -124,15 +125,15 @@ const char *_web_callPostRequest(int socketId, char *host, char *path, char *bod

namespace asio = boost::asio;

asio::io_context server_context{1};

int _web_getServerId(const char *addr, int port, int core) {
_web_init();
if (_server_context == nullptr){
_server_context = new boost::asio::io_context();
}
auto address = boost::asio::ip::make_address(addr);
auto acceptor = new tcp::acceptor{server_context, {address, static_cast<unsigned short>(port)}};
auto acceptor = new tcp::acceptor{*_server_context, {address, static_cast<unsigned short>(port)}};
char *path = new char[BUFSIZ];
getcwd(path, BUFSIZ);
auto servers = new std::vector<_web_HttpWorker *>(core);
auto servers = new std::vector<_web_HttpWorker *>;
while (core--) {
auto server = new _web_HttpWorker(*acceptor, std::string(path));
servers->push_back(server);
Expand Down Expand Up @@ -170,7 +171,7 @@ int _web_startServe(int sId) {
(*worker)->start();
worker++;
}
server_context.run();
_server_context->run();
return ROK;
}

Expand Down Expand Up @@ -271,7 +272,7 @@ void _web_HttpWorker::sendNotExistResponse() {
str_resp->keep_alive(false);
str_resp->set(http::field::server, SERVER_NAME);
str_resp->set(http::field::content_type, "application/json");
str_resp->body() = "您可能访问了一个错误的地址|URL requested not mapped.";
str_resp->body() = "您可能访问了一个错误的地址 | URL requested not mapped.";
// 计算相应长度
str_resp->prepare_payload();
str_serializer = std::make_unique<http::response_serializer<http::string_body>>(*str_resp);
Expand Down
3 changes: 2 additions & 1 deletion module/web/src/web.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ namespace beast = boost::beast;
extern boost::asio::io_context *_web_io_context;
extern tcp::resolver *_web_resolver;
extern map<int, tcp::socket *> _web_tcp_socket_map;
extern boost::asio::io_context* _server_context;

// Keep 函数名,方便Linking
extern "C" {
Expand Down Expand Up @@ -114,7 +115,7 @@ int _web_addUrlHandler(int sId, const char *method, const char *path, const char
* @param sId server id
* @return 状态
*/
int _web_startServe(int sId, int core);
int _web_startServe(int sId);
}

typedef const char *HandlerFunction();
Expand Down
46 changes: 15 additions & 31 deletions test/test.c
Original file line number Diff line number Diff line change
@@ -1,35 +1,19 @@
str example_func(int a){
return 'this is server response string';
str hi() {
str a = 'hello from kingtous compiler';
ret a;
}

void call_func(func<str,int> f){
str resp = f(5);
echo('resp is',resp);
}

int main(){
echo('init web framework', '123', '345');
int socketId = getSocket();
echo('socket id is',socketId);
str url = 'file.kingtous.cn';
str port = '443';
echo('url is:',url,' port is:',port);
int state = connectSocket(socketId,url,port);
state = isSocketConnected(socketId);
if (state == 0){
echo('socket connected');
echo('sending get request');
str response = getRequest(socketId,url,'/');
echo('response is:');
echo(response);
}
closeSocket(socketId);
int main() {
echo('init...');
echo(hi());
str host = '127.0.0.1';
int port = 9000;
int core = 2;
echo('get server...');
int server_id = getServer(host, port, core);
echo('server id is', server_id);
addUrlHandler(server_id, 'POST', '/compiler', hi);
echo('start server in host', host, ',port is', port);
startServer(server_id);
ret 0;
}

/**
* 获取path对应的mime type
* @param path
* @return mime type
*/
boost::beast::string_view mime_type(boost::beast::string_view path);
Loading

0 comments on commit a0b6e5c

Please sign in to comment.