Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
YottaChain
YTBP
提交
748f75da
Y
YTBP
项目概览
YottaChain
/
YTBP
通知
0
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
Y
YTBP
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
748f75da
编写于
3月 11, 2018
作者:
B
Bucky Kittinger
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Issue with injected code failing unexpectedly
上级
9c9d2243
变更
12
展开全部
隐藏空白更改
内联
并排
Showing
12 changed file
with
729 addition
and
725 deletion
+729
-725
CMakeLists.txt
CMakeLists.txt
+1
-2
libraries/chain/CMakeLists.txt
libraries/chain/CMakeLists.txt
+0
-1
libraries/chain/include/eosio/chain/wasm_eosio_binary_ops.hpp
...aries/chain/include/eosio/chain/wasm_eosio_binary_ops.hpp
+475
-449
libraries/chain/include/eosio/chain/wasm_eosio_injection.hpp
libraries/chain/include/eosio/chain/wasm_eosio_injection.hpp
+48
-96
libraries/chain/include/eosio/chain/wasm_eosio_validators.hpp
...aries/chain/include/eosio/chain/wasm_eosio_validators.hpp
+39
-24
libraries/chain/wasm_eosio_binary_ops.cpp
libraries/chain/wasm_eosio_binary_ops.cpp
+31
-25
libraries/chain/wasm_eosio_injection.cpp
libraries/chain/wasm_eosio_injection.cpp
+3
-8
libraries/chain/wasm_interface.cpp
libraries/chain/wasm_interface.cpp
+96
-113
libraries/chain/webassembly/binaryen.cpp
libraries/chain/webassembly/binaryen.cpp
+2
-2
libraries/chain/webassembly/wavm.cpp
libraries/chain/webassembly/wavm.cpp
+1
-3
libraries/wasm-jit/Include/IR/Operators.h
libraries/wasm-jit/Include/IR/Operators.h
+1
-0
libraries/wasm-jit/Include/IR/Types.h
libraries/wasm-jit/Include/IR/Types.h
+32
-2
未找到文件。
CMakeLists.txt
浏览文件 @
748f75da
...
@@ -119,7 +119,6 @@ else( WIN32 ) # Apple AND Linux
...
@@ -119,7 +119,6 @@ else( WIN32 ) # Apple AND Linux
#if(NOT READLINE_INCLUDE_DIR OR NOT READLINE_LIBRARIES)
#if(NOT READLINE_INCLUDE_DIR OR NOT READLINE_LIBRARIES)
# MESSAGE(FATAL_ERROR "Could not find lib readline.")
# MESSAGE(FATAL_ERROR "Could not find lib readline.")
#endif()
#endif()
if
(
APPLE
)
if
(
APPLE
)
# Apple Specific Options Here
# Apple Specific Options Here
message
(
STATUS
"Configuring Eos on OS X"
)
message
(
STATUS
"Configuring Eos on OS X"
)
...
@@ -128,7 +127,7 @@ else( WIN32 ) # Apple AND Linux
...
@@ -128,7 +127,7 @@ else( WIN32 ) # Apple AND Linux
else
(
APPLE
)
else
(
APPLE
)
# Linux Specific Options Here
# Linux Specific Options Here
message
(
STATUS
"Configuring Eos on Linux"
)
message
(
STATUS
"Configuring Eos on Linux"
)
set
(
CMAKE_CXX_FLAGS
"
${
CMAKE_C_FLAGS
}
-Wall"
)
set
(
CMAKE_CXX_FLAGS
"
${
CMAKE_C_FLAGS
}
-
std=c++1z -Wc++1z-extensions -
Wall"
)
if
(
FULL_STATIC_BUILD
)
if
(
FULL_STATIC_BUILD
)
set
(
CMAKE_EXE_LINKER_FLAGS
"
${
CMAKE_EXE_LINKER_FLAGS
}
-static-libstdc++ -static-libgcc"
)
set
(
CMAKE_EXE_LINKER_FLAGS
"
${
CMAKE_EXE_LINKER_FLAGS
}
-static-libstdc++ -static-libgcc"
)
endif
(
FULL_STATIC_BUILD
)
endif
(
FULL_STATIC_BUILD
)
...
...
libraries/chain/CMakeLists.txt
浏览文件 @
748f75da
...
@@ -11,7 +11,6 @@ add_library( eosio_chain
...
@@ -11,7 +11,6 @@ add_library( eosio_chain
wasm_interface.cpp
wasm_interface.cpp
wasm_eosio_constraints.cpp
wasm_eosio_constraints.cpp
wasm_eosio_injection.cpp
wasm_eosio_injection.cpp
wasm_eosio_binary_ops.cpp
wasm_module_walker.cpp
wasm_module_walker.cpp
apply_context.cpp
apply_context.cpp
rate_limiting.cpp
rate_limiting.cpp
...
...
libraries/chain/include/eosio/chain/wasm_eosio_binary_ops.hpp
浏览文件 @
748f75da
此差异已折叠。
点击以展开。
libraries/chain/include/eosio/chain/wasm_eosio_injection.hpp
浏览文件 @
748f75da
...
@@ -5,95 +5,51 @@
...
@@ -5,95 +5,51 @@
#include <functional>
#include <functional>
#include <vector>
#include <vector>
#include <iostream>
#include <iostream>
#include <map>
#include "IR/Module.h"
#include "IR/Module.h"
#include "IR/Operators.h"
#include "IR/Operators.h"
#include "WASM/WASM.h"
#include "WASM/WASM.h"
namespace
eosio
{
namespace
chain
{
namespace
wasm_injections
{
// module validators
namespace
eosio
{
namespace
chain
{
namespace
wasm_injections
{
// effectively do nothing and pass
using
namespace
IR
;
struct
noop_injection_visitor
{
// helper functions for injection
static
void
inject
(
IR
::
Module
&
m
);
static
void
initializer
();
struct
injector_utils
{
};
//static std::unordered_map<type_slot_pair, uint32_t, tsp_hasher > type_slots;
/*
static
std
::
map
<
std
::
vector
<
uint16_t
>
,
uint32_t
>
type_slots
;
static U32 checktimeIndex(const Module& module)
static
void
init
()
{
type_slots
.
clear
();
}
{
return module.functions.imports.size() - 1;
template
<
ResultType
Result
,
ValueType
...
Params
>
}
static
void
add_type_slot
(
Module
&
mod
)
{
if
(
type_slots
.
find
({
FromResultType
<
Result
>::
value
,
FromValueType
<
Params
>::
value
...})
==
type_slots
.
end
()
)
{
void setTypeSlot(const Module& module, ResultType returnType, const std::vector<ValueType>& parameterTypes)
type_slots
.
emplace
(
std
::
vector
<
uint16_t
>
{
FromResultType
<
Result
>::
value
,
FromValueType
<
Params
>::
value
...},
mod
.
types
.
size
()
);
{
mod
.
types
.
push_back
(
FunctionType
::
get
(
Result
,
{
Params
...
}
)
);
if (returnType == ResultType::none && parameterTypes.size() == 1 && parameterTypes[0] == ValueType::i32 )
}
typeSlot = module.types.size() - 1;
}
void addTypeSlot(Module& module)
{
if (typeSlot < 0)
{
// add a type for void func(void)
typeSlot = module.types.size();
module.types.push_back(FunctionType::get(ResultType::none, std::vector<ValueType>(1, ValueType::i32)));
}
}
}
void addImport(Module& module)
template
<
ResultType
Result
,
ValueType
...
Params
>
{
static
void
add_import
(
Module
&
module
,
const
char
*
scope
,
const
char
*
func_name
,
int32_t
&
index
)
{
if (module.functions.imports.size() == 0 || module.functions.imports.back().exportName.compare(u8"checktime") != 0) {
if
(
module
.
functions
.
imports
.
size
()
==
0
||
module
.
functions
.
imports
.
back
().
exportName
.
compare
(
func_name
)
!=
0
)
{
if (typeSlot < 0) {
add_type_slot
<
Result
,
Params
...
>
(
module
);
addTypeSlot(module);
const
uint32_t
func_type_index
=
type_slots
[{
FromResultType
<
Result
>::
value
,
FromValueType
<
Params
>::
value
...
}];
module
.
functions
.
imports
.
push_back
({{
func_type_index
},
std
::
move
(
scope
),
std
::
move
(
func_name
)});
index
=
module
.
functions
.
imports
.
size
()
-
1
;
// shift all exported functions by 1
for
(
int
i
=
0
;
i
<
module
.
exports
.
size
();
i
++
)
{
if
(
module
.
exports
[
i
].
kind
==
IR
::
ObjectKind
::
function
)
module
.
exports
[
i
].
index
+=
1
;
}
}
}
const U32 functionTypeIndex = typeSlot;
module.functions.imports.push_back({{functionTypeIndex}, std::move(u8"env"), std::move(u8"checktime")});
}
}
}
};
void conditionallyAddCall(Opcode opcode, const ControlStructureImm& imm, Module& module, OperatorEncoderStream& operatorEncoderStream, CodeValidationStream& codeValidationStream)
{
switch(opcode)
{
case Opcode::loop:
case Opcode::block:
addCall(module, operatorEncoderStream, codeValidationStream);
default:
break;
};
}
template<typename Imm>
void conditionallyAddCall(Opcode , const Imm& , Module& , OperatorEncoderStream& , CodeValidationStream& )
{
}
void adjustIfFunctionIndex(Uptr& index, ObjectKind kind)
{
if (kind == ObjectKind::function)
++index;
}
void adjustExportIndex(Module& module)
{
// all function exports need to have their index increased to account for inserted definition
for (auto& exportDef : module.exports)
{
adjustIfFunctionIndex(exportDef.index, exportDef.kind);
}
}
void adjustCallIndex(const Module& module, CallImm& imm)
{
if (imm.functionIndex >= checktimeIndex(module))
++imm.functionIndex;
}
template<typename Imm>
struct
noop_injection_visitor
{
void adjustCallIndex(const Module& , Imm& )
static
void
inject
(
IR
::
Module
&
m
);
{
static
void
initializer
();
}
}
;
*/
struct
memories_injection_visitor
{
struct
memories_injection_visitor
{
static
void
inject
(
IR
::
Module
&
m
);
static
void
inject
(
IR
::
Module
&
m
);
...
@@ -114,7 +70,7 @@ namespace eosio { namespace chain { namespace wasm_injections {
...
@@ -114,7 +70,7 @@ namespace eosio { namespace chain { namespace wasm_injections {
static
void
inject
(
IR
::
Module
&
m
);
static
void
inject
(
IR
::
Module
&
m
);
static
void
initializer
();
static
void
initializer
();
};
};
struct
blacklist_injection_visitor
{
struct
blacklist_injection_visitor
{
static
void
inject
(
IR
::
Module
&
m
);
static
void
inject
(
IR
::
Module
&
m
);
static
void
initializer
();
static
void
initializer
();
...
@@ -138,6 +94,7 @@ namespace eosio { namespace chain { namespace wasm_injections {
...
@@ -138,6 +94,7 @@ namespace eosio { namespace chain { namespace wasm_injections {
struct
debug_printer
{
struct
debug_printer
{
static
constexpr
bool
kills
=
false
;
static
constexpr
bool
kills
=
false
;
static
void
init
()
{}
static
void
accept
(
wasm_ops
::
instr
*
inst
,
wasm_ops
::
visitor_arg
&
arg
)
{
static
void
accept
(
wasm_ops
::
instr
*
inst
,
wasm_ops
::
visitor_arg
&
arg
)
{
std
::
cout
<<
"INSTRUCTION : "
<<
inst
->
to_string
()
<<
"
\n
"
;
std
::
cout
<<
"INSTRUCTION : "
<<
inst
->
to_string
()
<<
"
\n
"
;
}
}
...
@@ -145,6 +102,7 @@ namespace eosio { namespace chain { namespace wasm_injections {
...
@@ -145,6 +102,7 @@ namespace eosio { namespace chain { namespace wasm_injections {
struct
instruction_counter
{
struct
instruction_counter
{
static
constexpr
bool
kills
=
false
;
static
constexpr
bool
kills
=
false
;
static
void
init
()
{
icnt
=
0
;
}
static
void
accept
(
wasm_ops
::
instr
*
inst
,
wasm_ops
::
visitor_arg
&
arg
)
{
static
void
accept
(
wasm_ops
::
instr
*
inst
,
wasm_ops
::
visitor_arg
&
arg
)
{
// maybe change this later to variable weighting for different instruction types
// maybe change this later to variable weighting for different instruction types
icnt
++
;
icnt
++
;
...
@@ -154,22 +112,23 @@ namespace eosio { namespace chain { namespace wasm_injections {
...
@@ -154,22 +112,23 @@ namespace eosio { namespace chain { namespace wasm_injections {
struct
checktime_injector
{
struct
checktime_injector
{
static
constexpr
bool
kills
=
false
;
static
constexpr
bool
kills
=
false
;
static
void
init
()
{
checktime_idx
=
-
1
;
}
static
void
accept
(
wasm_ops
::
instr
*
inst
,
wasm_ops
::
visitor_arg
&
arg
)
{
static
void
accept
(
wasm_ops
::
instr
*
inst
,
wasm_ops
::
visitor_arg
&
arg
)
{
// if (checktime_idx == -1)
// first add the import for checktime
// FC_THROW("Error, this should be run after module injector"
);
injector_utils
::
add_import
<
ResultType
::
none
,
ValueType
::
i32
>
(
*
(
arg
.
module
),
u8"env"
,
u8"checktime"
,
checktime_idx
);
//std::cout << "HIT A BLOCK " << " " << index << "\n";
wasm_ops
::
op_types
<>::
i32_const_t
cnt
;
wasm_ops
::
op_types
<>::
i32_const_t
cnt
;
cnt
.
field
=
instruction_counter
::
icnt
;
cnt
.
field
=
instruction_counter
::
icnt
;
wasm_ops
::
op_types
<>::
call_t
chktm
;
wasm_ops
::
op_types
<>::
call_t
chktm
;
chktm
.
field
=
checktime_idx
;
chktm
.
field
=
checktime_idx
;
instruction_counter
::
icnt
=
0
;
instruction_counter
::
icnt
=
0
;
// pack the ops for insertion
// pack the ops for insertion
std
::
vector
<
U8
>
injected
=
cnt
.
pack
();
std
::
vector
<
U8
>
injected
=
cnt
.
pack
();
std
::
vector
<
U8
>
tmp
=
chktm
.
pack
();
std
::
vector
<
U8
>
tmp
=
chktm
.
pack
();
injected
.
insert
(
injected
.
end
(),
tmp
.
begin
(),
tmp
.
end
()
);
injected
.
insert
(
injected
.
end
(),
tmp
.
begin
(),
tmp
.
end
()
);
//arg.new_code->insert( arg.new_code->end(), injected.begin(), injected.end() );
arg
.
new_code
->
insert
(
arg
.
new_code
->
end
(),
injected
.
begin
(),
injected
.
end
()
);
//arg.function_def->code.insert( arg.function_def->code.begin()+arg.code_index,
// injected.begin(), injected.end() );
}
}
static
int32_t
checktime_idx
;
static
int32_t
checktime_idx
;
};
};
...
@@ -327,8 +286,9 @@ namespace eosio { namespace chain { namespace wasm_injections {
...
@@ -327,8 +286,9 @@ namespace eosio { namespace chain { namespace wasm_injections {
wasm_binary_injection
()
{
wasm_binary_injection
()
{
_module_injectors
.
init
();
_module_injectors
.
init
();
// initialize static fields of injectors
// initialize static fields of injectors
instruction_counter
::
icnt
=
0
;
//injector_utils::init();
checktime_injector
::
checktime_idx
=
-
1
;
instruction_counter
::
init
();
checktime_injector
::
init
();
}
}
static
void
inject
(
IR
::
Module
&
mod
)
{
static
void
inject
(
IR
::
Module
&
mod
)
{
...
@@ -338,17 +298,9 @@ namespace eosio { namespace chain { namespace wasm_injections {
...
@@ -338,17 +298,9 @@ namespace eosio { namespace chain { namespace wasm_injections {
std
::
vector
<
U8
>
new_code
;
std
::
vector
<
U8
>
new_code
;
while
(
decoder
)
{
while
(
decoder
)
{
auto
op
=
decoder
.
decodeOp
();
auto
op
=
decoder
.
decodeOp
();
std
::
vector
<
U8
>::
iterator
decoded_index
=
(
fd
.
code
.
begin
()
+
decoder
.
index
());
op
->
visit
(
{
&
mod
,
&
new_code
,
&
fd
,
decoder
.
index
()
}
);
op
->
visit
(
{
&
mod
,
&
new_code
,
&
fd
,
decoder
.
index
()
}
);
}
}
for
(
int
i
=
0
;
i
<
new_code
.
size
();
i
++
)
std
::
cout
<<
std
::
hex
<<
uint32_t
(
new_code
[
i
])
<<
", "
;
std
::
cout
<<
"
\n
"
;
for
(
int
i
=
0
;
i
<
fd
.
code
.
size
();
i
++
)
std
::
cout
<<
std
::
hex
<<
uint32_t
(
fd
.
code
[
i
])
<<
", "
;
std
::
cout
<<
"
\n
"
;
fd
.
code
=
new_code
;
fd
.
code
=
new_code
;
}
}
}
}
...
...
libraries/chain/include/eosio/chain/wasm_eosio_validators.hpp
浏览文件 @
748f75da
#pragma once
#pragma once
#include <fc/exception/exception.hpp>
#include <fc/exception/exception.hpp>
#include <eosio/chain/exceptions.hpp>
#include <eosio/chain/wasm_eosio_binary_ops.hpp>
#include <eosio/chain/wasm_eosio_binary_ops.hpp>
#include <functional>
#include <functional>
#include <vector>
#include <vector>
...
@@ -48,6 +49,8 @@ namespace eosio { namespace chain { namespace wasm_constraints {
...
@@ -48,6 +49,8 @@ namespace eosio { namespace chain { namespace wasm_constraints {
// instruction validators
// instruction validators
// simple mutator that doesn't actually mutate anything
// simple mutator that doesn't actually mutate anything
// used to verify that a given instruction is valid for execution on our platform
// used to verify that a given instruction is valid for execution on our platform
// for validators set kills to true, this eliminates the extraneous building
// of new code that is going to get thrown away any way
struct
whitelist_validator
{
struct
whitelist_validator
{
static
constexpr
bool
kills
=
true
;
static
constexpr
bool
kills
=
true
;
static
void
accept
(
wasm_ops
::
instr
*
inst
,
wasm_ops
::
visitor_arg
&
arg
)
{
static
void
accept
(
wasm_ops
::
instr
*
inst
,
wasm_ops
::
visitor_arg
&
arg
)
{
...
@@ -55,6 +58,17 @@ namespace eosio { namespace chain { namespace wasm_constraints {
...
@@ -55,6 +58,17 @@ namespace eosio { namespace chain { namespace wasm_constraints {
}
}
};
};
struct
large_offset_validator
{
static
constexpr
bool
kills
=
true
;
static
void
accept
(
wasm_ops
::
instr
*
inst
,
wasm_ops
::
visitor_arg
&
arg
)
{
// cast to a type that has a memarg field
wasm_ops
::
op_types
<>::
i32_load_t
*
memarg_instr
=
reinterpret_cast
<
wasm_ops
::
op_types
<>::
i32_load_t
*>
(
inst
);
if
(
memarg_instr
->
field
.
o
>=
wasm_constraints
::
maximum_linear_memory
)
FC_THROW_EXCEPTION
(
wasm_execution_error
,
"Smart contract used an invalid large memory store/load offset"
);
}
};
struct
wasm_opcode_no_disposition_exception
{
struct
wasm_opcode_no_disposition_exception
{
std
::
string
opcode_name
;
std
::
string
opcode_name
;
};
};
...
@@ -62,7 +76,8 @@ namespace eosio { namespace chain { namespace wasm_constraints {
...
@@ -62,7 +76,8 @@ namespace eosio { namespace chain { namespace wasm_constraints {
struct
blacklist_validator
{
struct
blacklist_validator
{
static
constexpr
bool
kills
=
true
;
static
constexpr
bool
kills
=
true
;
static
void
accept
(
wasm_ops
::
instr
*
inst
,
wasm_ops
::
visitor_arg
&
arg
)
{
static
void
accept
(
wasm_ops
::
instr
*
inst
,
wasm_ops
::
visitor_arg
&
arg
)
{
throw
wasm_opcode_no_disposition_exception
{
inst
->
to_string
()
};
FC_THROW_EXCEPTION
(
wasm_execution_error
,
"Error, blacklisted opcode ${op} "
,
(
"op"
,
inst
->
to_string
()));
}
}
};
};
...
@@ -92,29 +107,29 @@ namespace eosio { namespace chain { namespace wasm_constraints {
...
@@ -92,29 +107,29 @@ namespace eosio { namespace chain { namespace wasm_constraints {
using
set_global_t
=
wasm_ops
::
set_global
<
whitelist_validator
>
;
using
set_global_t
=
wasm_ops
::
set_global
<
whitelist_validator
>
;
using
nop_t
=
wasm_ops
::
nop
<
whitelist_validator
>
;
using
nop_t
=
wasm_ops
::
nop
<
whitelist_validator
>
;
using
i32_load_t
=
wasm_ops
::
i32_load
<
whitelist_validator
>
;
using
i32_load_t
=
wasm_ops
::
i32_load
<
large_offset_validator
,
whitelist_validator
>
;
using
i64_load_t
=
wasm_ops
::
i64_load
<
whitelist_validator
>
;
using
i64_load_t
=
wasm_ops
::
i64_load
<
large_offset_validator
,
whitelist_validator
>
;
using
f32_load_t
=
wasm_ops
::
f32_load
<
whitelist_validator
>
;
using
f32_load_t
=
wasm_ops
::
f32_load
<
large_offset_validator
,
whitelist_validator
>
;
using
f64_load_t
=
wasm_ops
::
f64_load
<
whitelist_validator
>
;
using
f64_load_t
=
wasm_ops
::
f64_load
<
large_offset_validator
,
whitelist_validator
>
;
using
i32_load8_s_t
=
wasm_ops
::
i32_load8_s
<
whitelist_validator
>
;
using
i32_load8_s_t
=
wasm_ops
::
i32_load8_s
<
large_offset_validator
,
whitelist_validator
>
;
using
i32_load8_u_t
=
wasm_ops
::
i32_load8_u
<
whitelist_validator
>
;
using
i32_load8_u_t
=
wasm_ops
::
i32_load8_u
<
large_offset_validator
,
whitelist_validator
>
;
using
i32_load16_s_t
=
wasm_ops
::
i32_load16_s
<
whitelist_validator
>
;
using
i32_load16_s_t
=
wasm_ops
::
i32_load16_s
<
large_offset_validator
,
whitelist_validator
>
;
using
i32_load16_u_t
=
wasm_ops
::
i32_load16_u
<
whitelist_validator
>
;
using
i32_load16_u_t
=
wasm_ops
::
i32_load16_u
<
large_offset_validator
,
whitelist_validator
>
;
using
i64_load8_s_t
=
wasm_ops
::
i64_load8_s
<
whitelist_validator
>
;
using
i64_load8_s_t
=
wasm_ops
::
i64_load8_s
<
large_offset_validator
,
whitelist_validator
>
;
using
i64_load8_u_t
=
wasm_ops
::
i64_load8_u
<
whitelist_validator
>
;
using
i64_load8_u_t
=
wasm_ops
::
i64_load8_u
<
large_offset_validator
,
whitelist_validator
>
;
using
i64_load16_s_t
=
wasm_ops
::
i64_load16_s
<
whitelist_validator
>
;
using
i64_load16_s_t
=
wasm_ops
::
i64_load16_s
<
large_offset_validator
,
whitelist_validator
>
;
using
i64_load16_u_t
=
wasm_ops
::
i64_load16_u
<
whitelist_validator
>
;
using
i64_load16_u_t
=
wasm_ops
::
i64_load16_u
<
large_offset_validator
,
whitelist_validator
>
;
using
i64_load32_s_t
=
wasm_ops
::
i64_load32_s
<
whitelist_validator
>
;
using
i64_load32_s_t
=
wasm_ops
::
i64_load32_s
<
large_offset_validator
,
whitelist_validator
>
;
using
i64_load32_u_t
=
wasm_ops
::
i64_load32_u
<
whitelist_validator
>
;
using
i64_load32_u_t
=
wasm_ops
::
i64_load32_u
<
large_offset_validator
,
whitelist_validator
>
;
using
i32_store_t
=
wasm_ops
::
i32_store
<
whitelist_validator
>
;
using
i32_store_t
=
wasm_ops
::
i32_store
<
large_offset_validator
,
whitelist_validator
>
;
using
i64_store_t
=
wasm_ops
::
i64_store
<
whitelist_validator
>
;
using
i64_store_t
=
wasm_ops
::
i64_store
<
large_offset_validator
,
whitelist_validator
>
;
using
f32_store_t
=
wasm_ops
::
f32_store
<
whitelist_validator
>
;
using
f32_store_t
=
wasm_ops
::
f32_store
<
large_offset_validator
,
whitelist_validator
>
;
using
f64_store_t
=
wasm_ops
::
f64_store
<
whitelist_validator
>
;
using
f64_store_t
=
wasm_ops
::
f64_store
<
large_offset_validator
,
whitelist_validator
>
;
using
i32_store8_t
=
wasm_ops
::
i32_store8
<
whitelist_validator
>
;
using
i32_store8_t
=
wasm_ops
::
i32_store8
<
large_offset_validator
,
whitelist_validator
>
;
using
i32_store16_t
=
wasm_ops
::
i32_store16
<
whitelist_validator
>
;
using
i32_store16_t
=
wasm_ops
::
i32_store16
<
large_offset_validator
,
whitelist_validator
>
;
using
i64_store8_t
=
wasm_ops
::
i64_store8
<
whitelist_validator
>
;
using
i64_store8_t
=
wasm_ops
::
i64_store8
<
large_offset_validator
,
whitelist_validator
>
;
using
i64_store16_t
=
wasm_ops
::
i64_store16
<
whitelist_validator
>
;
using
i64_store16_t
=
wasm_ops
::
i64_store16
<
large_offset_validator
,
whitelist_validator
>
;
using
i64_store32_t
=
wasm_ops
::
i64_store32
<
whitelist_validator
>
;
using
i64_store32_t
=
wasm_ops
::
i64_store32
<
large_offset_validator
,
whitelist_validator
>
;
using
i32_const_t
=
wasm_ops
::
i32_const
<
whitelist_validator
>
;
using
i32_const_t
=
wasm_ops
::
i32_const
<
whitelist_validator
>
;
using
i64_const_t
=
wasm_ops
::
i64_const
<
whitelist_validator
>
;
using
i64_const_t
=
wasm_ops
::
i64_const
<
whitelist_validator
>
;
...
...
libraries/chain/wasm_eosio_binary_ops.cpp
浏览文件 @
748f75da
...
@@ -9,57 +9,63 @@
...
@@ -9,57 +9,63 @@
namespace
eosio
{
namespace
chain
{
namespace
wasm_ops
{
namespace
eosio
{
namespace
chain
{
namespace
wasm_ops
{
using
namespace
IR
;
using
namespace
IR
;
std
::
string
to_string
(
NoImm
imm
)
{
inline
std
::
string
to_string
(
NoImm
imm
)
{
return
"no imm"
;
return
"no imm"
;
}
}
std
::
string
to_string
(
MemoryImm
imm
)
{
inline
std
::
string
to_string
(
MemoryImm
imm
)
{
return
"memory imm"
;
return
"memory imm"
;
}
}
std
::
string
to_string
(
CallImm
imm
)
{
inline
std
::
string
to_string
(
CallImm
imm
)
{
return
"call index : "
+
std
::
to_string
(
uint32_t
(
imm
.
functionIndex
));
return
"call index : "
+
std
::
to_string
(
uint32_t
(
imm
.
functionIndex
));
}
}
std
::
string
to_string
(
CallIndirectImm
imm
)
{
inline
std
::
string
to_string
(
CallIndirectImm
imm
)
{
return
"call indirect type : "
+
std
::
to_string
(
uint32_t
(
imm
.
type
.
index
));
return
"call indirect type : "
+
std
::
to_string
(
uint32_t
(
imm
.
type
.
index
));
}
}
std
::
string
to_string
(
uint32_t
field
)
{
inline
std
::
string
to_string
(
uint32_t
field
)
{
return
std
::
string
(
"i32 : "
)
+
std
::
to_string
(
field
);
return
std
::
string
(
"i32 : "
)
+
std
::
to_string
(
field
);
}
}
std
::
string
to_string
(
uint64_t
field
)
{
inline
std
::
string
to_string
(
uint64_t
field
)
{
return
std
::
string
(
"i64 : "
)
+
std
::
to_string
(
field
);
return
std
::
string
(
"i64 : "
)
+
std
::
to_string
(
field
);
}
}
std
::
string
to_string
(
blocktype
field
)
{
inline
std
::
string
to_string
(
blocktype
field
)
{
return
std
::
string
(
"blocktype : "
)
+
std
::
to_string
((
uint32_t
)
field
.
result
);
return
std
::
string
(
"blocktype : "
)
+
std
::
to_string
((
uint32_t
)
field
.
result
);
}
}
std
::
string
to_string
(
memoryoptype
field
)
{
inline
std
::
string
to_string
(
memoryoptype
field
)
{
return
std
::
string
(
"memoryoptype : "
)
+
std
::
to_string
((
uint32_t
)
field
.
end
);
return
std
::
string
(
"memoryoptype : "
)
+
std
::
to_string
((
uint32_t
)
field
.
end
);
}
}
std
::
string
to_string
(
memarg
field
)
{
inline
std
::
string
to_string
(
memarg
field
)
{
return
std
::
string
(
"memarg : "
)
+
std
::
to_string
(
field
.
a
)
+
std
::
string
(
", "
)
+
std
::
to_string
(
field
.
o
);
return
std
::
string
(
"memarg : "
)
+
std
::
to_string
(
field
.
a
)
+
std
::
string
(
", "
)
+
std
::
to_string
(
field
.
o
);
}
}
std
::
string
to_string
(
callindirecttype
field
)
{
inline
std
::
string
to_string
(
branchtabletype
field
)
{
return
std
::
string
(
"callindirecttype : "
)
+
return
std
::
string
(
"branchtabletype : "
)
+
std
::
to_string
(
field
.
target_depth
)
+
std
::
string
(
", "
)
+
std
::
to_string
(
field
.
table_index
);
std
::
to_string
(
field
.
funcidx
)
+
std
::
string
(
", "
)
+
std
::
to_string
((
uint32_t
)
field
.
end
);
}
}
std
::
vector
<
U8
>
pack
(
uint32_t
field
)
{
inline
std
::
vector
<
U8
>
pack
(
uint32_t
field
)
{
return
{
U8
(
field
>>
24
),
U8
(
field
>>
16
),
U8
(
field
>>
8
),
U8
(
field
)
};
return
{
U8
(
field
),
U8
(
field
>>
8
),
U8
(
field
>>
16
),
U8
(
field
>>
24
)
};
}
}
std
::
vector
<
U8
>
pack
(
uint64_t
field
)
{
inline
std
::
vector
<
U8
>
pack
(
uint64_t
field
)
{
return
{
U8
(
field
>>
56
),
U8
(
field
>>
48
),
U8
(
field
>>
40
),
U8
(
field
>>
32
),
return
{
U8
(
field
),
U8
(
field
>>
8
),
U8
(
field
>>
16
),
U8
(
field
>>
24
),
U8
(
field
>>
24
),
U8
(
field
>>
16
),
U8
(
field
>>
8
),
U8
(
field
)
};
U8
(
field
>>
32
),
U8
(
field
>>
40
),
U8
(
field
>>
48
),
U8
(
field
>>
56
)
};
}
}
std
::
vector
<
U8
>
pack
(
blocktype
field
)
{
inline
std
::
vector
<
U8
>
pack
(
blocktype
field
)
{
return
{
U8
(
field
.
result
)
};
return
{
U8
(
field
.
result
)
};
}
}
std
::
vector
<
U8
>
pack
(
memoryoptype
field
)
{
inline
std
::
vector
<
U8
>
pack
(
memoryoptype
field
)
{
return
{
U8
(
field
.
end
)
};
return
{
U8
(
field
.
end
)
};
}
}
std
::
vector
<
U8
>
pack
(
memarg
field
)
{
inline
std
::
vector
<
U8
>
pack
(
memarg
field
)
{
return
{
U8
(
field
.
a
>>
24
),
U8
(
field
.
a
>>
16
),
U8
(
field
.
a
>>
8
),
U8
(
field
.
a
),
return
{
U8
(
field
.
a
),
U8
(
field
.
a
>>
8
),
U8
(
field
.
a
>>
16
),
U8
(
field
.
a
>>
24
),
U8
(
field
.
o
>>
24
),
U8
(
field
.
o
>>
16
),
U8
(
field
.
o
>>
8
),
U8
(
field
.
o
)
};
U8
(
field
.
o
),
U8
(
field
.
o
>>
8
),
U8
(
field
.
o
>>
16
),
U8
(
field
.
o
>>
24
),
};
}
}
std
::
vector
<
U8
>
pack
(
callindirecttype
field
)
{
inline
std
::
vector
<
U8
>
pack
(
branchtabletype
field
)
{
return
{
U8
(
field
.
funcidx
>>
24
),
U8
(
field
.
funcidx
>>
16
),
U8
(
field
.
funcidx
>>
8
),
U8
(
field
.
funcidx
),
return
{
U8
(
field
.
target_depth
),
U8
(
field
.
target_depth
>>
8
),
U8
(
field
.
target_depth
>>
16
),
U8
(
field
.
target_depth
>>
24
),
U8
(
field
.
end
)
};
U8
(
field
.
target_depth
>>
32
),
U8
(
field
.
target_depth
>>
40
),
U8
(
field
.
target_depth
>>
48
),
U8
(
field
.
target_depth
>>
56
),
U8
(
field
.
table_index
),
U8
(
field
.
table_index
>>
8
),
U8
(
field
.
table_index
>>
16
),
U8
(
field
.
table_index
>>
24
),
U8
(
field
.
table_index
>>
32
),
U8
(
field
.
table_index
>>
40
),
U8
(
field
.
table_index
>>
48
),
U8
(
field
.
table_index
>>
56
)
};
}
}
}}}
// namespace eosio, chain, wasm_ops
}}}
// namespace eosio, chain, wasm_ops
libraries/chain/wasm_eosio_injection.cpp
浏览文件 @
748f75da
...
@@ -9,14 +9,9 @@
...
@@ -9,14 +9,9 @@
namespace
eosio
{
namespace
chain
{
namespace
wasm_injections
{
namespace
eosio
{
namespace
chain
{
namespace
wasm_injections
{
using
namespace
IR
;
using
namespace
IR
;
/*
std::string to_string( ControlStructureImm imm ) {
//std::unordered_map<type_slot_pair, uint32_t, tsp_hasher> injector_utils::type_slots;
return "result type : "+std::to_string(uint32_t(imm.resultType));
std
::
map
<
std
::
vector
<
uint16_t
>
,
uint32_t
>
injector_utils
::
type_slots
;
}
std::string to_string( BranchImm imm ) {
return "branch target : "+std::to_string(uint32_t(imm.targetDepth));
}
*/
void
noop_injection_visitor
::
inject
(
Module
&
m
)
{
/* just pass */
}
void
noop_injection_visitor
::
inject
(
Module
&
m
)
{
/* just pass */
}
void
noop_injection_visitor
::
initializer
()
{
/* just pass */
}
void
noop_injection_visitor
::
initializer
()
{
/* just pass */
}
...
...
libraries/chain/wasm_interface.cpp
浏览文件 @
748f75da
...
@@ -185,128 +185,110 @@ namespace eosio { namespace chain {
...
@@ -185,128 +185,110 @@ namespace eosio { namespace chain {
fc
::
optional
<
binaryen
::
info
>
binaryen_info
;
fc
::
optional
<
binaryen
::
info
>
binaryen_info
;
try
{
try
{
#if 0
IR
::
Module
*
module
=
new
IR
::
Module
();
IR
::
Module
*
module2
=
new
IR
::
Module
();
Serialization
::
MemoryInputStream
stream
((
const
U8
*
)
wasm_binary
,
wasm_binary_size
);
Serialization
::
MemoryInputStream
stream
((
const
U8
*
)
wasm_binary
,
wasm_binary_size
);
WASM::serializeWithInjection(stream, *module);
Serialization
::
MemoryInputStream
stream2
((
const
U8
*
)
wasm_binary
,
wasm_binary_size
);
validate_eosio_wasm_constraints(*module);
WASM
::
serialize
(
stream
,
*
module
);
wasm_module_walker<
WASM
::
serializeWithInjection
(
stream2
,
*
module2
);
wasm_constraints::constraints_validators<wasm_constraints::memories_validator,
wasm_constraints::data_segments_validator,
wasm_constraints
::
wasm_binary_validation
::
validate
(
*
module
);
wasm_constraints::tables_validator,
wasm_injections
::
wasm_binary_injection
::
inject
(
*
module
);
wasm_constraints::globals_validator>,
/*
wasm_constraints::constraints_validators<wasm_constraints::memories_validator,
std::cout << "INJECTED\n";
wasm_constraints::data_segments_validator,
wasm_injections::wasm_binary_injection::inject( *module );
wasm_constraints::tables_validator,
std::cout << "INJECTEDSS\n";
wasm_constraints::globals_validator>>
wasm_injections::wasm_binary_injection::inject( *module2 );
wmw(*module);
auto restype = [](IR::ResultType f){
wasm_ops::wasm_instr_ptr nopi = std::make_shared< wasm_ops::nop<test_mutator> >();
if (f == IR::ResultType::none ) return "none";
wasm_ops::wasm_instr_ptr blocki = std::make_shared< wasm_ops::block<test_mutator2> >();
if (f == IR::ResultType::i32 ) return "i32";
wasm_ops::op_types<test_mutator>::block_t b;
if (f == IR::ResultType::i64 ) return "i64";
wasm_ops::op_types<test_mutator>::i64_popcount_t ipc;
if (f == IR::ResultType::f32 ) return "f32";
wasm_ops::nop<test_mutator> n;
if (f == IR::ResultType::f64 ) return "f64";
wasm_ops::call<test_mutator> br;
};
br.field = 23;
auto valtype = [](IR::ValueType f){
wasm_rewriter::op_constrainers::f32_add_t f32;
if (f == IR::ValueType::any ) return "any";
b.visit();
if (f == IR::ValueType::i32 ) return "i32";
ipc.visit();
if (f == IR::ValueType::i64 ) return "i64";
wmw.pre_validate();
if (f == IR::ValueType::f32 ) return "f32";
for (auto def : module->functions.defs) {
if (f == IR::ValueType::f64 ) return "f64";
char* code = (char*)(def.code.data());
};
char* code_end = code+def.code.size();
std::cout << "FUNC " << "\n";
uint32_t it = 0;
std::cout << "FUNCTION_Type A \n";
/*
for (auto e : module->types) {
while ( it < def.code.size() ) {
std::cout << "Function ("<< restype(e->ret) << ") (";
std::cout << "OPCODE " << std::hex << (uint32_t)code[it] << "\n";
for (auto ee : e->parameters) {
it++;
std::cout << valtype(ee) << ", ";
}
*/
it = 0;
for (FunctionDef& fd : module->functions.defs ) {
OperatorDecoderStream decoder(fd.code);
while (decoder) {
std::cout << "OP " << std::hex << (uint32_t)decoder.decodeOp() << "\n";
wasm_ops::instr* op = wasm_ops::get_instr_from_op<wasm_ops::op_types<>>(*(decoder.index));
std::cout << "OP2 " << op->to_string() << " " << (uint32_t)((wasm_ops::i32_const<test_mutator>*)op)->field << "\n";
/*
if ( op->get_code() == 0x41 )
else
std::cout << "OP2 " << std::hex << (uint32_t)op->get_code() << " " << op->to_string() << "\n";
*/
}
}
}
/*
}
while ( it < def.code.size() ) {
std::cout << "\n";
std::cout << "OPCODE " << std::hex << (uint32_t)code[it] << "\n";
std::cout << "FUNCTION_Type B \n";
wasm_ops::instr* op = wasm_ops::get_instr_from_op<wasm_ops::op_types<>>(code[it]);
for (auto e : module->types) {
it = op->unpack( def.code, it );
std::cout << "Function ("<< restype(e->ret) << ") (";
if ( op->get_code() == 0x41 )
for (auto ee : e->parameters) {
std::cout << "OP " << op->to_string() << " " << (uint32_t)((wasm_ops::i32_const<test_mutator>*)op)->field << "\n";
std::cout << valtype(ee) << ", ";
else if ( op->get_code() == 0x42 )
std::cout << "OP " << op->to_string() << " " << (uint32_t)((wasm_ops::i32_const<test_mutator>*)op)->field << "\n";
else
std::cout << "OP " << op->to_string() << "\n";
}
}
*/
//std::cout << (int)n << " ";
}
}
/*
std::cout << "\n";
std::cout << "\n";
uint8_t* buff = new uint8_t[3];
buff[0] = wasm_ops::block_code;
std::cout << "FUNCTION_Import A \n";
buff[1] = 120;
for (auto e : module->functions.imports)
//buff[2] = wasm_ops::nop_code;
std::cout << e.exportName << "\n";
buff[2] = 34;
std::cout << "\n";
std::vector<uint8_t> code = {wasm_ops::block_code, 13, wasm_ops::nop_code};
std::cout << "FUNCTION_Import B \n";
// wasm_ops::instr* block_ = new wasm_ops::wasm_op_table::which_pointer<wasm_ops::op_types<test_mutator2>, wasm_ops::block_code>::instr_t((char*)buff);
for (auto e : module2->functions.imports)
// wasm_ops::instr* nop_ = new wasm_ops::wasm_op_table::which_pointer<wasm_ops::op_types<test_mutator2>, wasm_ops::nop_code>::instr_t(block_->skip_ahead((char*)buff));
std::cout << e.exportName << "\n";
wasm_ops::instr* block_ = wasm_ops::get_instr_from_op<wasm_ops::op_types<test_mutator2>>(wasm_ops::block_code);
wasm_ops::instr* nop_ = wasm_ops::get_instr_from_op<wasm_ops::op_types<test_mutator2>>(wasm_ops::nop_code);
std::cout << "\n";
std::cout << "TABLES_Import A \n";
datastream<uint8_t*> ds( code.data(), code.size() );
for (auto e : module->tables.imports)
std::cout << e.exportName << "\n";
//fc::raw::unpack(ds, *nop_);
block_->visit();
std::cout << "\n";
std::cout << "TABLES_Import B \n";
std::cout << "FIELD : " << (uint64_t)((wasm_ops::block<test_mutator>*)block_)->field.result << "\n";
for (auto e : module2->tables.imports)
std::cout << "CODE : " << (int)block_->get_code() << "NAME : " << block_->to_string() << "\n";
std::cout << e.exportName << "\n";
std::cout << "CODE : " << (int)nop_->get_code() << "NAME : " << nop_->to_string() << "\n";
std::cout << "\n";
std::cout << "MEMORIES_Import A \n";
for (auto e : module->memories.imports)
std::cout << e.exportName << "\n";
std::cout << "\n";
std::cout << "MEMORIES_Import B \n";
for (auto e : module2->memories.imports)
std::cout << e.exportName << "\n";
std::cout << "\n";
std::cout << "GLOBALS_Import A \n";
for (auto e : module->globals.imports)
std::cout << e.exportName << "\n";
std::cout << "\n";
std::cout << "GLOBALS_Import B \n";
for (auto e : module2->globals.imports)
std::cout << e.exportName << "\n";
std::cout << "\n";
std::cout << "EXPORT A \n";
for (auto e : module->exports)
std::cout << e.name << " " << uint32_t(e.index) << "\n";
std::cout << "\n";
std::cout << "EXPORT B \n";
for (auto e : module2->exports)
std::cout << e.name << " " << uint32_t(e.index) << "\n";
std::cout << "\n";
*/
*/
root_resolver resolver;
LinkResult link_result = linkModule(*module, resolver);
instance = instantiateModule(*module, std::move(link_result.resolvedImports));
FC_ASSERT(instance != nullptr);
//populate the module's data segments in to a vector so the initial state can be
// restored on each invocation
//Be Warned, this may need to be revisited when module imports make sense. The
// code won't handle data segments that initalize an imported memory which I think
// is valid.
for(const DataSegment& data_segment : module->dataSegments) {
FC_ASSERT(data_segment.baseOffset.type == InitializerExpression::Type::i32_const);
FC_ASSERT(module->memories.defs.size());
const U32 base_offset = data_segment.baseOffset.i32;
const Uptr memory_size = (module->memories.defs[0].type.size.min << IR::numBytesPerPageLog2);
if(base_offset >= memory_size || base_offset + data_segment.data.size() > memory_size)
FC_THROW_EXCEPTION(wasm_execution_error, "WASM data segment outside of valid memory range");
if(base_offset + data_segment.data.size() > mem_image.size())
mem_image.resize(base_offset + data_segment.data.size(), 0x00);
memcpy(mem_image.data() + base_offset, data_segment.data.data(), data_segment.data.size());
}
#endif
/// TODO: make validation generic
IR
::
Module
*
module
=
new
IR
::
Module
();
Serialization
::
MemoryInputStream
stream
((
const
U8
*
)
wasm_binary
,
wasm_binary_size
);
wasm_constraints
::
wasm_binary_validation
::
validate
(
*
module
);
WASM
::
serialize
(
stream
,
*
module
);
Serialization
::
ArrayOutputStream
outstream
;
wasm_constraints
::
wasm_binary_validation
::
validate
(
*
module
);
wasm_injections
::
wasm_binary_injection
::
inject
(
*
module
);
Serialization
::
ArrayOutputStream
outstream
;
WASM
::
serialize
(
outstream
,
*
module
);
WASM
::
serialize
(
outstream
,
*
module
);
std
::
vector
<
U8
>
bytes
=
outstream
.
getBytes
();
std
::
vector
<
U8
>
bytes
=
outstream
.
getBytes
();
wavm
=
wavm
::
entry
::
build
((
char
*
)
bytes
.
data
(),
bytes
.
size
());
wavm
=
wavm
::
entry
::
build
((
char
*
)
bytes
.
data
(),
bytes
.
size
());
wavm_info
.
emplace
(
*
wavm
);
wavm_info
.
emplace
(
*
wavm
);
...
@@ -613,6 +595,7 @@ public:
...
@@ -613,6 +595,7 @@ public:
using
context_aware_api
::
context_aware_api
;
using
context_aware_api
::
context_aware_api
;
void
checktime
(
uint32_t
instruction_count
)
{
void
checktime
(
uint32_t
instruction_count
)
{
std
::
cout
<<
"CHECKTIME
\n
"
;
context
.
checktime
(
instruction_count
);
context
.
checktime
(
instruction_count
);
}
}
};
};
...
...
libraries/chain/webassembly/binaryen.cpp
浏览文件 @
748f75da
...
@@ -159,7 +159,7 @@ entry entry::build(const char* wasm_binary, size_t wasm_binary_size) {
...
@@ -159,7 +159,7 @@ entry entry::build(const char* wasm_binary, size_t wasm_binary_size) {
WasmBinaryBuilder
builder
(
*
module
,
code
,
false
);
WasmBinaryBuilder
builder
(
*
module
,
code
,
false
);
builder
.
read
();
builder
.
read
();
inject_checktime
(
*
module
.
get
());
//
inject_checktime(*module.get());
FC_ASSERT
(
module
->
memory
.
initial
*
Memory
::
kPageSize
<=
wasm_constraints
::
maximum_linear_memory
);
FC_ASSERT
(
module
->
memory
.
initial
*
Memory
::
kPageSize
<=
wasm_constraints
::
maximum_linear_memory
);
...
@@ -226,4 +226,4 @@ entry::entry(unique_ptr<Module>&& module, linear_memory_type&& memory, call_indi
...
@@ -226,4 +226,4 @@ entry::entry(unique_ptr<Module>&& module, linear_memory_type&& memory, call_indi
}
}
}}}}
}}}}
\ No newline at end of file
libraries/chain/webassembly/wavm.cpp
浏览文件 @
748f75da
...
@@ -120,9 +120,7 @@ void entry::prepare( const info& base_info ) {
...
@@ -120,9 +120,7 @@ void entry::prepare( const info& base_info ) {
entry
entry
::
build
(
const
char
*
wasm_binary
,
size_t
wasm_binary_size
)
{
entry
entry
::
build
(
const
char
*
wasm_binary
,
size_t
wasm_binary_size
)
{
Module
*
module
=
new
Module
();
Module
*
module
=
new
Module
();
Serialization
::
MemoryInputStream
stream
((
const
U8
*
)
wasm_binary
,
wasm_binary_size
);
Serialization
::
MemoryInputStream
stream
((
const
U8
*
)
wasm_binary
,
wasm_binary_size
);
WASM
::
serializeWithInjection
(
stream
,
*
module
);
WASM
::
serialize
(
stream
,
*
module
);
// TODO clean this up
//validate_eosio_wasm_constraints(*module);
root_resolver
resolver
;
root_resolver
resolver
;
LinkResult
link_result
=
linkModule
(
*
module
,
resolver
);
LinkResult
link_result
=
linkModule
(
*
module
,
resolver
);
...
...
libraries/wasm-jit/Include/IR/Operators.h
浏览文件 @
748f75da
...
@@ -25,6 +25,7 @@ namespace IR
...
@@ -25,6 +25,7 @@ namespace IR
struct
BranchTableImm
struct
BranchTableImm
{
{
static_assert
(
sizeof
(
Uptr
)
==
8
,
"SIZEE"
);
Uptr
defaultTargetDepth
;
Uptr
defaultTargetDepth
;
Uptr
branchTableIndex
;
// An index into the FunctionDef's branchTables array.
Uptr
branchTableIndex
;
// An index into the FunctionDef's branchTables array.
};
};
...
...
libraries/wasm-jit/Include/IR/Types.h
浏览文件 @
748f75da
...
@@ -26,6 +26,21 @@ namespace IR
...
@@ -26,6 +26,21 @@ namespace IR
max
=
num
-
1
max
=
num
-
1
};
};
template
<
ValueType
type
>
struct
FromValueType
;
template
<
>
struct
FromValueType
<
ValueType
::
any
>
{
static
constexpr
uint16_t
value
=
0
;
};
template
<
>
struct
FromValueType
<
ValueType
::
i32
>
{
static
constexpr
uint16_t
value
=
1
;
};
template
<
>
struct
FromValueType
<
ValueType
::
i64
>
{
static
constexpr
uint16_t
value
=
2
;
};
template
<
>
struct
FromValueType
<
ValueType
::
f32
>
{
static
constexpr
uint16_t
value
=
3
;
};
template
<
>
struct
FromValueType
<
ValueType
::
f64
>
{
static
constexpr
uint16_t
value
=
4
;
};
template
<
uint16_t
type
>
struct
ToValueType
;
template
<
>
struct
ToValueType
<
0
>
{
static
constexpr
ValueType
value
=
ValueType
::
any
;
};
template
<
>
struct
ToValueType
<
1
>
{
static
constexpr
ValueType
value
=
ValueType
::
i32
;
};
template
<
>
struct
ToValueType
<
2
>
{
static
constexpr
ValueType
value
=
ValueType
::
i64
;
};
template
<
>
struct
ToValueType
<
3
>
{
static
constexpr
ValueType
value
=
ValueType
::
f32
;
};
template
<
>
struct
ToValueType
<
4
>
{
static
constexpr
ValueType
value
=
ValueType
::
f64
;
};
template
<
ValueType
type
>
struct
ValueTypeInfo
;
template
<
ValueType
type
>
struct
ValueTypeInfo
;
template
<
>
struct
ValueTypeInfo
<
ValueType
::
i32
>
{
typedef
I32
Value
;
};
template
<
>
struct
ValueTypeInfo
<
ValueType
::
i32
>
{
typedef
I32
Value
;
};
template
<
>
struct
ValueTypeInfo
<
ValueType
::
i64
>
{
typedef
I64
Value
;
};
template
<
>
struct
ValueTypeInfo
<
ValueType
::
i64
>
{
typedef
I64
Value
;
};
...
@@ -128,7 +143,22 @@ namespace IR
...
@@ -128,7 +143,22 @@ namespace IR
num
,
num
,
max
=
num
-
1
,
max
=
num
-
1
,
};
};
template
<
uint16_t
type
>
struct
ToResultType
;
template
<
>
struct
ToResultType
<
0
>
{
static
constexpr
ResultType
value
=
ResultType
::
none
;
};
template
<
>
struct
ToResultType
<
1
>
{
static
constexpr
ResultType
value
=
ResultType
::
i32
;
};
template
<
>
struct
ToResultType
<
2
>
{
static
constexpr
ResultType
value
=
ResultType
::
i64
;
};
template
<
>
struct
ToResultType
<
3
>
{
static
constexpr
ResultType
value
=
ResultType
::
f32
;
};
template
<
>
struct
ToResultType
<
4
>
{
static
constexpr
ResultType
value
=
ResultType
::
f64
;
};
template
<
ResultType
type
>
struct
FromResultType
;
template
<
>
struct
FromResultType
<
ResultType
::
none
>
{
static
constexpr
uint16_t
value
=
0
;
};
template
<
>
struct
FromResultType
<
ResultType
::
i32
>
{
static
constexpr
uint16_t
value
=
1
;
};
template
<
>
struct
FromResultType
<
ResultType
::
i64
>
{
static
constexpr
uint16_t
value
=
2
;
};
template
<
>
struct
FromResultType
<
ResultType
::
f32
>
{
static
constexpr
uint16_t
value
=
3
;
};
template
<
>
struct
FromResultType
<
ResultType
::
f64
>
{
static
constexpr
uint16_t
value
=
4
;
};
inline
Uptr
getArity
(
ResultType
returnType
)
{
return
returnType
==
ResultType
::
none
?
0
:
1
;
}
inline
Uptr
getArity
(
ResultType
returnType
)
{
return
returnType
==
ResultType
::
none
?
0
:
1
;
}
inline
const
char
*
asString
(
ResultType
type
)
inline
const
char
*
asString
(
ResultType
type
)
...
@@ -337,4 +367,4 @@ namespace IR
...
@@ -337,4 +367,4 @@ namespace IR
default:
Errors
::
unreachable
();
default:
Errors
::
unreachable
();
};
};
}
}
}
}
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录