Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
YottaChain
YTBP
提交
cad995f0
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,发现更多精彩内容 >>
提交
cad995f0
编写于
3月 08, 2018
作者:
B
Bucky Kittinger
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
cached instruction objects
上级
1cac79ed
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
116 addition
and
34 deletion
+116
-34
libraries/chain/include/eosio/chain/wasm_binary_ops.hpp
libraries/chain/include/eosio/chain/wasm_binary_ops.hpp
+116
-32
libraries/chain/wasm_binary_ops.cpp
libraries/chain/wasm_binary_ops.cpp
+0
-2
未找到文件。
libraries/chain/include/eosio/chain/wasm_binary_ops.hpp
浏览文件 @
cad995f0
...
...
@@ -2,6 +2,7 @@
#include <boost/preprocessor/seq/for_each.hpp>
#include <boost/preprocessor/seq/subseq.hpp>
#include <boost/preprocessor/seq/remove.hpp>
#include <fc/reflect/reflect.hpp>
#include <cstdint>
...
...
@@ -36,14 +37,9 @@ struct no_param_op {
struct
block_param_op
{
};
//FC_ASSERT(start <= block.end(), "Error while unpacking code");
#define CONSTRUCT_OP( r, DATA, OP ) \
template <typename ... Mutators> \
struct OP : instr_base<Mutators...> { \
OP() = default; \
OP( char* block ) {} \
uint8_t code = BOOST_PP_CAT(OP,_code); \
uint8_t get_code() { return BOOST_PP_CAT(OP,_code); } \
int skip_ahead() { return sizeof(code); } \
...
...
@@ -53,15 +49,10 @@ struct OP : instr_base<Mutators...> { \
} \
std::string to_string() { return BOOST_PP_STRINGIZE(OP); } \
};
// char* unpack( char* block ) { return ++block; } \
// std::vector<char> pack() { return { code }; } \
//};
#define CONSTRUCT_OP_HAS_DATA( r, DATA, OP ) \
template <typename ... Mutators> \
struct OP : instr_base<Mutators...> { \
OP() = default; \
OP( char* block ) { code = *((uint8_t*)(block++)); field = *((DATA*)(block)); } \
uint8_t code = BOOST_PP_CAT(OP,_code); \
DATA field; \
uint8_t get_code() { return BOOST_PP_CAT(OP,_code); } \
...
...
@@ -70,20 +61,9 @@ struct OP : instr_base<Mutators...> {
field = *((DATA*)(block.data()+start+sizeof(code))); \
return start + skip_ahead(); \
} \
std::string to_string() { return BOOST_PP_STRINGIZE(OP); }
\
std::string to_string() { return BOOST_PP_STRINGIZE(OP); } \
};
/*
char* unpack( char* block ) { return block + 1 + sizeof(DATA); } \
std::vector<char> pack() { \
std::vector<char> ret_vec = { code }; \
std::vector<char> field_vec = fc::raw::pack(field); \
return ret_vec.insert( ret_vec.end(), field_vec.begin(), field_vec.end() ); \
} \
};
*/
#define WASM_OP_SEQ (error) \
(end) \
(unreachable) \
...
...
@@ -615,24 +595,127 @@ struct nop_mutator {
static
wasm_return_t
accept
(
instr
*
inst
)
{}
};
#define GEN_TYPE( r, T, OP ) \
using BOOST_PP_CAT( OP, _t ) = OP < T , BOOST_PP_CAT(T, s) ...>;
// class to inherit from to attach specific mutators and have default behavior for all specified types
template
<
typename
Mutator
=
nop_mutator
,
typename
...
Mutators
>
struct
op_types
{
#define GEN_TYPE( r, T, OP ) \
using BOOST_PP_CAT( OP, _t ) = OP < T , BOOST_PP_CAT(T, s) ...>;
BOOST_PP_SEQ_FOR_EACH
(
GEN_TYPE
,
Mutator
,
WASM_OP_SEQ
)
#undef GEN_TYPE
};
// op_types
/**
* Section for cached ops
*/
//TODO maybe come back to this
#if 0
// tuple for flattening for "cached" ops
template <uint8_t OpCode, class Op_Types>
struct cached_ops_tuple_impl {
static constexpr auto value = std::tuple_cat( std::make_tuple( get_error_instr<Op_Types> ), cached_ops_tuple_impl<OpCode+1, Op_Types>::value );
};
template <class Op_Types>
struct cached_ops_tuple_impl<0xFF, Op_Types> {
static constexpr auto value = std::make_tuple( get_error_instr<Op_Types> );
};
#define GEN_CACHED_OP_SPECIALIZATIONS( r, T, OP ) \
template <class Op_Types> \
struct cached_ops_tuple_impl<wasm_ops::BOOST_PP_CAT(OP,_code), Op_Types> { \
static constexpr auto value = std::tuple_cat( std::make_tuple( 3 ), \
cached_ops_tuple_impl<BOOST_PP_CAT(OP,_code)+1, Op_Types>::value ); \
};
[](){ \
static auto ptr = std::make_unique<typename Op_Types::BOOST_PP_CAT(OP,_t)>(); \
return *ptr; \
}), \
cached_ops_tuple_impl<BOOST_PP_CAT(OP,_code)+1, Op_Types>::value ); \
};
BOOST_PP_SEQ_FOR_EACH( GEN_CACHED_OP_SPECIALIZATIONS, cached_, BOOST_PP_SEQ_REMOVE(WASM_OP_SEQ, 0) )
#undef GEN_CACHED_OP_SPECIALIZATIONS
template <typename Func, std::size_t N, typename Ops_Tuple, std::size_t... I>
constexpr auto cached_ops_flatten_impl( const Ops_Tuple& a, std::index_sequence<I...>) { return std::array<Func, N>{ std::get<I>(a)...}; }
template <typename Head, typename... Rest>
constexpr auto cached_ops_flatten( const std::tuple<Head, Rest...>& ops ) {
constexpr auto N = sizeof...(Rest)+1;
return cached_ops_flatten_impl<Head, N, std::tuple<Head, Rest...>>( ops, std::make_index_sequence<N>());
}
template <class Op_Types>
constexpr auto generate_cached_ops() {
return cached_ops_flatten( cached_ops_tuple_impl<0x0, Op_Types>::value );
}
template <class Op_Types>
instr* get_error_instr() {
static auto ptr = std::make_unique<typename Op_Types::error_t>();
return *ptr;
}
template <uint8_t Op_Code, class Op_Types>
struct op_instr_func {
static constexpr auto value = get_error_instr<Op_Types>;
};
//base case
template <class Op_Types>
struct op_instr_func<0xFF, Op_Types> {
static constexpr auto value = get_error_instr<Op_Types>;
};
#define GEN_OP_INSTR_FUNC_SPECIALIZATION( r, T, OP ) \
template <class Op_Types> \
struct op_instr_func<BOOST_PP_CAT(OP, _code), Op_Types> { \
static constexpr std::function<instr*()> value = [](){ \
static auto ptr = std::make_unique<typename Op_Types::BOOST_PP_CAT(OP,_t)>(); \
return *ptr; \
}; \
};
BOOST_PP_SEQ_FOR_EACH( GEN_OP_INSTR_FUNC_SPECIALIZATION, , BOOST_PP_SEQ_REMOVE(WASM_OP_SEQ, 0) )
#undef GEN_OP_INSTR_FUNC_SPECIALIZATION
#endif
template
<
class
Op_Types
>
std
::
vector
<
instr
*>*
get_cached_ops_vec
()
{
#define GEN_FIELD( r, P, OP ) \
static typename Op_Types::BOOST_PP_CAT(OP,_t) BOOST_PP_CAT(P, OP);
BOOST_PP_SEQ_FOR_EACH
(
GEN_FIELD
,
cached_
,
WASM_OP_SEQ
)
#undef GEN_FIELD
static
std
::
vector
<
instr
*>
_cached_ops
;
#define PUSH_BACK_OP( r, T, OP ) \
_cached_ops.push_back( &BOOST_PP_CAT(T, OP) );
if
(
_cached_ops
.
empty
()
)
{
BOOST_PP_SEQ_FOR_EACH
(
PUSH_BACK_OP
,
cached_
,
WASM_OP_SEQ
)
}
#undef PUSH_BACK_OP
return
&
_cached_ops
;
}
// simple struct to house a set of instaniated ops that we can take the reference from
template
<
class
Op_Types
>
struct
cached_ops
{
/*
#define GEN_FIELD( r, P, OP ) \
typename Op_Types::BOOST_PP_CAT(OP,_t) BOOST_PP_CAT(P, OP);
BOOST_PP_SEQ_FOR_EACH( GEN_FIELD, cached_, WASM_OP_SEQ )
#undef GEN_FIELD
*/
static
std
::
vector
<
instr
*>*
cache
;
};
template
<
class
Op_Types
>
std
::
vector
<
instr
*>*
cached_ops
<
Op_Types
>::
cache
=
get_cached_ops_vec
<
Op_Types
>
();
// Decodes an operator from an input stream and dispatches by opcode.
// This code is from wasm-jit/Include/IR/Operators.h
template
<
class
Op_Types
>
...
...
@@ -643,6 +726,7 @@ struct EOSIO_OperatorDecoderStream
operator
bool
()
const
{
return
nextByte
<
end
;
}
// IR::OpcodeAndImm<IR::Imm>* encodedOperator = (IR::OpcodeAndImm<IR::Imm>*)nextByte; \//
instr
*
decodeOp
()
{
assert
(
nextByte
+
sizeof
(
IR
::
Opcode
)
<=
end
);
...
...
@@ -653,19 +737,17 @@ struct EOSIO_OperatorDecoderStream
case IR::Opcode::name: \
{ \
assert(nextByte + sizeof(IR::OpcodeAndImm<IR::Imm>) <= end); \
IR::OpcodeAndImm<IR::Imm>* encodedOperator = (IR::OpcodeAndImm<IR::Imm>*)nextByte; \
nextByte += sizeof(IR::OpcodeAndImm<IR::Imm>); \
auto op =
&_cached_ops.BOOST_PP_CAT(cached_, name
); \
return
op
; \
auto op =
_cached_ops.cache->at(BOOST_PP_CAT(name, _code)
); \
return
nullptr
; \
}
ENUM_OPERATORS
(
VISIT_OPCODE
)
#undef VISIT_OPCODE
default:
nextByte
+=
sizeof
(
IR
::
Opcode
);
return
&
_cached_ops
.
cached_error
;
return
nullptr
;
// cached_ops[error_code]()
;
}
}
instr
*
decodeOpWithoutConsume
()
{
const
U8
*
savedNextByte
=
nextByte
;
...
...
@@ -673,9 +755,11 @@ struct EOSIO_OperatorDecoderStream
nextByte
=
savedNextByte
;
return
result
;
}
private:
static
cached_ops
<
Op_Types
>
_cached_ops
;
// cached ops to take the address of
//static constexpr auto cached_ops = generate_cached_ops<Op_Types>();
//static constexpr auto cached_ops = cached_ops_tuple_impl<0x30, Op_Types>::value;
static
const
cached_ops
<
Op_Types
>
_cached_ops
;
const
U8
*
nextByte
;
const
U8
*
end
;
};
...
...
libraries/chain/wasm_binary_ops.cpp
浏览文件 @
cad995f0
#include <eosio/chain/wasm_binary_ops.hpp>
namespace
eosio
{
namespace
chain
{
namespace
wasm_ops
{
std
::
unordered_map
<
uint8_t
,
wasm_op_generator
>
=
{
{
UNREACHABLE
,
[](
std
::
vector
<
uint8_t
>&
vec
,
size_t
index
){
return
std
::
make_shared
<
unreachable
}}}
// namespace eosio, chain, wasm_ops
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录