-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcommon.cpp
152 lines (120 loc) · 3.83 KB
/
common.cpp
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
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#include "common.hpp"
//#define DEBUG_DISABLE_JIT
#include <iostream>
#include <scriptarray/scriptarray.h>
#include <scriptbuilder/scriptbuilder.h>
#include <scriptstdstring/scriptstdstring.h>
#include <stdexcept>
std::stringstream out;
namespace bindings
{
void message_callback(const asSMessageInfo* info, [[maybe_unused]] void* param)
{
const char* message_type = nullptr;
switch (info->type)
{
case asMSGTYPE_INFORMATION:
{
message_type = "INFO";
break;
}
case asMSGTYPE_WARNING:
{
message_type = "WARN";
break;
}
default:
{
message_type = "ERR ";
break;
}
}
std::cerr << info->section << ':' << info->row << ':' << info->col << ": " << message_type << ": " << info->message
<< '\n';
}
void print(const std::string& message) { out << message << '\n'; }
void print_int(long value) { out << value << '\n'; }
void print_uint(unsigned long value) { out << value << '\n'; }
void print_char(char value) { out << value; }
} // namespace bindings
EngineContext::EngineContext(asllvm::JitConfig config) : engine{asCreateScriptEngine()}, jit{config}
{
engine->SetEngineProperty(asEP_INCLUDE_JIT_INSTRUCTIONS, true);
#ifndef DEBUG_DISABLE_JIT
asllvm_test_check(engine->SetJITCompiler(&jit) >= 0);
#endif
register_interface();
}
EngineContext::~EngineContext() { engine->ShutDownAndRelease(); }
void EngineContext::register_interface()
{
RegisterStdString(engine);
RegisterScriptArray(engine, true);
asllvm_test_check(
engine->RegisterGlobalFunction("void print(const string &in)", asFUNCTION(bindings::print), asCALL_CDECL) >= 0);
asllvm_test_check(
engine->RegisterGlobalFunction("void print(int64)", asFUNCTION(bindings::print_int), asCALL_CDECL) >= 0);
asllvm_test_check(
engine->RegisterGlobalFunction("void print(uint64)", asFUNCTION(bindings::print_uint), asCALL_CDECL) >= 0);
asllvm_test_check(
engine->RegisterGlobalFunction("void putchar(uint8)", asFUNCTION(bindings::print_char), asCALL_CDECL) >= 0);
asllvm_test_check(engine->SetMessageCallback(asFUNCTION(bindings::message_callback), nullptr, asCALL_CDECL) >= 0);
}
asIScriptModule& EngineContext::build(const char* name, const char* script_path)
{
CScriptBuilder builder;
asllvm_test_check(builder.StartNewModule(engine, name) >= 0);
asllvm_test_check(builder.AddSectionFromFile(script_path) >= 0);
asllvm_test_check(builder.BuildModule() >= 0);
return *engine->GetModule(name);
}
void EngineContext::prepare_execution()
{
#ifndef DEBUG_DISABLE_JIT
jit.BuildModules();
#endif
}
void EngineContext::run(asIScriptModule& module, const char* entry_point)
{
prepare_execution();
asIScriptFunction* function = module.GetFunctionByDecl(entry_point);
asllvm_test_check(function != nullptr);
asIScriptContext* context = engine->CreateContext();
asllvm_test_check(context->Prepare(function) >= 0);
asllvm_test_check(context->Execute() == asEXECUTION_FINISHED);
context->Release();
}
asllvm::JitConfig default_jit_config()
{
asllvm::JitConfig config;
config.verbose = true;
config.allow_llvm_optimizations = false;
return config;
}
std::string run(const char* path, const char* entry)
{
EngineContext context(default_jit_config());
return run(context, path, entry);
}
std::string run(EngineContext& context, const char* path, const char* entry)
{
out = {};
asIScriptModule& module = context.build("build", path);
context.run(module, entry);
return out.str();
}
std::string run_string(const char* str)
{
EngineContext context(default_jit_config());
return run_string(context, str);
}
std::string run_string(EngineContext& context, const char* str)
{
out = {};
CScriptBuilder builder;
builder.StartNewModule(context.engine, "build");
builder.AddSectionFromMemory("str", (std::string("void main() {") + str + ";}").c_str());
builder.BuildModule();
context.run(*context.engine->GetModule("build"), "void main()");
return out.str();
}