Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
YottaChain
YTBP
提交
9a614ead
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,发现更多精彩内容 >>
提交
9a614ead
编写于
2月 12, 2018
作者:
B
Bart Wyatt
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
more modularization
上级
7ea3f14c
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
114 addition
and
72 deletion
+114
-72
libraries/chain/CMakeLists.txt
libraries/chain/CMakeLists.txt
+1
-0
libraries/chain/include/eosio/chain/webassembly/jit.hpp
libraries/chain/include/eosio/chain/webassembly/jit.hpp
+39
-9
libraries/chain/wasm_interface.cpp
libraries/chain/wasm_interface.cpp
+13
-63
libraries/chain/webassembly/jit.cpp
libraries/chain/webassembly/jit.cpp
+61
-0
未找到文件。
libraries/chain/CMakeLists.txt
浏览文件 @
9a614ead
...
...
@@ -27,6 +27,7 @@ add_library( eosio_chain
contracts/genesis_state.cpp
contracts/abi_serializer.cpp
webassembly/jit.cpp
${
HEADERS
}
transaction_metadata.cpp
)
...
...
libraries/chain/include/eosio/chain/webassembly/jit.hpp
浏览文件 @
9a614ead
...
...
@@ -12,6 +12,7 @@ using namespace eosio::chain::webassembly::common;
namespace
eosio
{
namespace
chain
{
namespace
webassembly
{
namespace
jit
{
struct
info
;
struct
entry
{
entry
(
ModuleInstance
*
instance
,
Module
*
module
)
:
instance
(
instance
),
module
(
module
)
...
...
@@ -20,10 +21,39 @@ struct entry {
ModuleInstance
*
instance
;
Module
*
module
;
void
reset
(
const
info
&
);
static
const
entry
&
get
(
wasm_interface
&
wasm
);
static
entry
build
(
const
char
*
wasm_binary
,
size_t
wasm_binary_size
);
};
struct
info
{
info
(
const
entry
&
jit
)
{
MemoryInstance
*
current_memory
=
Runtime
::
getDefaultMemory
(
jit
.
instance
);
if
(
current_memory
)
{
char
*
mem_ptr
=
&
memoryRef
<
char
>
(
current_memory
,
0
);
const
auto
allocated_memory
=
Runtime
::
getDefaultMemorySize
(
jit
.
instance
);
for
(
uint64_t
i
=
0
;
i
<
allocated_memory
;
++
i
)
{
if
(
mem_ptr
[
i
])
mem_end
=
i
+
1
;
}
mem_image
.
resize
(
mem_end
);
memcpy
(
mem_image
.
data
(),
mem_ptr
,
mem_end
);
}
}
// a clean image of the memory used to sanitize things on checkin
size_t
mem_start
=
0
;
size_t
mem_end
=
1
<<
16
;
vector
<
char
>
mem_image
;
};
/**
* class to represent an in-wasm-memory array
* it is a hint to the transcriber that the next parameter will
...
...
@@ -32,7 +62,7 @@ struct entry {
* @tparam T
*/
template
<
typename
T
>
array_ptr
<
T
>
array_ptr_impl
(
wasm_interface
&
wasm
,
U32
ptr
,
size_t
length
)
inline
array_ptr
<
T
>
array_ptr_impl
(
wasm_interface
&
wasm
,
U32
ptr
,
size_t
length
)
{
auto
mem
=
getDefaultMemory
(
entry
::
get
(
wasm
).
instance
);
if
(
!
mem
||
ptr
+
length
>
IR
::
numBytesPerPage
*
Runtime
::
getMemoryNumPages
(
mem
))
...
...
@@ -44,7 +74,7 @@ array_ptr<T> array_ptr_impl (wasm_interface& wasm, U32 ptr, size_t length)
/**
* class to represent an in-wasm-memory char array that must be null terminated
*/
null_terminated_ptr
null_terminated_ptr_impl
(
wasm_interface
&
wasm
,
U32
ptr
)
inline
null_terminated_ptr
null_terminated_ptr_impl
(
wasm_interface
&
wasm
,
U32
ptr
)
{
auto
mem
=
getDefaultMemory
(
entry
::
get
(
wasm
).
instance
);
if
(
!
mem
)
...
...
@@ -128,19 +158,19 @@ template<typename T>
using
native_to_wasm_t
=
typename
native_to_wasm
<
T
>::
type
;
template
<
typename
T
>
auto
convert_native_to_wasm
(
const
wasm_interface
&
wasm
,
T
val
)
{
inline
auto
convert_native_to_wasm
(
const
wasm_interface
&
wasm
,
T
val
)
{
return
native_to_wasm_t
<
T
>
(
val
);
}
auto
convert_native_to_wasm
(
const
wasm_interface
&
wasm
,
const
name
&
val
)
{
inline
auto
convert_native_to_wasm
(
const
wasm_interface
&
wasm
,
const
name
&
val
)
{
return
native_to_wasm_t
<
const
name
&>
(
val
.
value
);
}
auto
convert_native_to_wasm
(
const
wasm_interface
&
wasm
,
const
fc
::
time_point_sec
&
val
)
{
inline
auto
convert_native_to_wasm
(
const
wasm_interface
&
wasm
,
const
fc
::
time_point_sec
&
val
)
{
return
native_to_wasm_t
<
const
fc
::
time_point_sec
&>
(
val
.
sec_since_epoch
());
}
auto
convert_native_to_wasm
(
wasm_interface
&
wasm
,
char
*
ptr
)
{
inline
auto
convert_native_to_wasm
(
wasm_interface
&
wasm
,
char
*
ptr
)
{
auto
mem
=
getDefaultMemory
(
entry
::
get
(
wasm
).
instance
);
if
(
!
mem
)
Runtime
::
causeException
(
Exception
::
Cause
::
accessViolation
);
...
...
@@ -152,12 +182,12 @@ auto convert_native_to_wasm(wasm_interface &wasm, char* ptr) {
}
template
<
typename
T
>
auto
convert_wasm_to_native
(
native_to_wasm_t
<
T
>
val
)
{
inline
auto
convert_wasm_to_native
(
native_to_wasm_t
<
T
>
val
)
{
return
T
(
val
);
}
template
<
>
auto
convert_wasm_to_native
<
wasm_double
>
(
I64
val
)
{
inline
auto
convert_wasm_to_native
<
wasm_double
>
(
I64
val
)
{
return
wasm_double
(
*
reinterpret_cast
<
wasm_double
*>
(
&
val
));
}
...
...
libraries/chain/wasm_interface.cpp
浏览文件 @
9a614ead
...
...
@@ -4,7 +4,6 @@
#include <eosio/chain/exceptions.hpp>
#include <boost/core/ignore_unused.hpp>
#include <eosio/chain/wasm_interface_private.hpp>
#include <eosio/chain/wasm_eosio_constraints.hpp>
#include <fc/exception/exception.hpp>
#include <fc/crypto/sha1.hpp>
#include <fc/io/raw.hpp>
...
...
@@ -72,26 +71,6 @@ namespace eosio { namespace chain {
using
namespace
webassembly
;
using
namespace
webassembly
::
common
;
/**
* Integration with the WASM Linker to resolve our intrinsics
*/
struct
root_resolver
:
Runtime
::
Resolver
{
bool
resolve
(
const
string
&
mod_name
,
const
string
&
export_name
,
ObjectType
type
,
ObjectInstance
*&
out
)
override
{
try
{
// Try to resolve an intrinsic first.
if
(
IntrinsicResolver
::
singleton
.
resolve
(
mod_name
,
export_name
,
type
,
out
))
{
return
true
;
}
FC_ASSERT
(
!
"unresolvable"
,
"${module}.${export}"
,
(
"module"
,
mod_name
)(
"export"
,
export_name
)
);
return
false
;
}
FC_CAPTURE_AND_RETHROW
(
(
mod_name
)(
export_name
)
)
}
};
/**
* Implementation class for the wasm cache
* it is responsible for compiling and storing instances of wasm code for use
...
...
@@ -127,14 +106,8 @@ namespace eosio { namespace chain {
* the instance handed out to other threads
*/
struct
code_info
{
code_info
(
size_t
mem_end
,
vector
<
char
>&&
mem_image
)
:
mem_end
(
mem_end
),
mem_image
(
std
::
forward
<
vector
<
char
>>
(
mem_image
))
{}
// a clean image of the memory used to sanitize things on checkin
size_t
mem_start
=
0
;
size_t
mem_end
=
1
<<
16
;
vector
<
char
>
mem_image
;
explicit
code_info
(
jit
::
info
&&
jit_info
)
:
jit_info
(
jit_info
)
{}
jit
::
info
jit_info
;
// all existing instances of this code
vector
<
unique_ptr
<
wasm_cache
::
entry
>>
instances
;
...
...
@@ -215,33 +188,14 @@ namespace eosio { namespace chain {
if
(
!
pending_result
)
{
// time to compile a brand new (maybe first) copy of this code
Module
*
module
=
new
Module
();
ModuleInstance
*
instance
=
nullptr
;
size_t
mem_end
=
0
;
vector
<
char
>
mem_image
;
fc
::
optional
<
jit
::
entry
>
jit
;
fc
::
optional
<
jit
::
info
>
jit_info
;
try
{
Serialization
::
MemoryInputStream
stream
((
const
U8
*
)
wasm_binary
,
wasm_binary_size
);
WASM
::
serializeWithInjection
(
stream
,
*
module
);
validate_eosio_wasm_constraints
(
*
module
);
root_resolver
resolver
;
LinkResult
link_result
=
linkModule
(
*
module
,
resolver
);
instance
=
instantiateModule
(
*
module
,
std
::
move
(
link_result
.
resolvedImports
));
FC_ASSERT
(
instance
!=
nullptr
);
MemoryInstance
*
current_memory
=
Runtime
::
getDefaultMemory
(
instance
);
if
(
current_memory
)
{
char
*
mem_ptr
=
&
memoryRef
<
char
>
(
current_memory
,
0
);
const
auto
allocated_memory
=
Runtime
::
getDefaultMemorySize
(
instance
);
for
(
uint64_t
i
=
0
;
i
<
allocated_memory
;
++
i
)
{
if
(
mem_ptr
[
i
])
mem_end
=
i
+
1
;
}
mem_image
.
resize
(
mem_end
);
memcpy
(
mem_image
.
data
(),
mem_ptr
,
mem_end
);
}
/// TODO: make validation generic
jit
=
jit
::
entry
::
build
(
wasm_binary
,
wasm_binary_size
);
jit_info
.
emplace
(
*
jit
);
}
catch
(...)
{
pending_error
=
std
::
current_exception
();
...
...
@@ -251,12 +205,13 @@ namespace eosio { namespace chain {
// grab the lock and put this in the cache as unavailble
with_lock
(
_cache_lock
,
[
&
,
this
]()
{
// find or create a new entry
auto
iter
=
_cache
.
emplace
(
code_id
,
code_info
(
mem_end
,
std
::
move
(
mem_image
))).
first
;
auto
iter
=
_cache
.
emplace
(
code_id
,
code_info
(
std
::
move
(
*
jit_info
))).
first
;
MemoryInstance
*
default_mem
=
Runtime
::
getDefaultMemory
(
instance
);
/// TODO: make sbrk bytes generic
MemoryInstance
*
default_mem
=
Runtime
::
getDefaultMemory
(
jit
->
instance
);
uint32_t
default_sbrk_bytes
=
default_mem
?
Runtime
::
getMemoryNumPages
(
default_mem
)
<<
IR
::
numBytesPerPageLog2
:
0
;
iter
->
second
.
instances
.
emplace_back
(
std
::
make_unique
<
wasm_cache
::
entry
>
(
jit
::
entry
{
instance
,
module
}
,
default_sbrk_bytes
));
iter
->
second
.
instances
.
emplace_back
(
std
::
make_unique
<
wasm_cache
::
entry
>
(
std
::
move
(
*
jit
)
,
default_sbrk_bytes
));
pending_result
=
optional_entry_ref
(
*
iter
->
second
.
instances
.
back
().
get
());
});
}
...
...
@@ -291,12 +246,7 @@ namespace eosio { namespace chain {
void
return_entry
(
const
digest_type
&
code_id
,
wasm_cache
::
entry
&
entry
)
{
// sanitize by reseting the memory that may now be dirty
auto
&
info
=
(
*
fetch_info
(
code_id
)).
get
();
if
(
getDefaultMemory
(
entry
.
jit
.
instance
))
{
char
*
memstart
=
&
memoryRef
<
char
>
(
getDefaultMemory
(
entry
.
jit
.
instance
),
0
);
memset
(
memstart
+
info
.
mem_end
,
0
,
((
1
<<
16
)
-
info
.
mem_end
)
);
memcpy
(
memstart
,
info
.
mem_image
.
data
(),
info
.
mem_end
);
}
resetGlobalInstances
(
entry
.
jit
.
instance
);
entry
.
jit
.
reset
(
info
.
jit_info
);
// under a lock, put this entry back in the available instances side of the instances vector
with_lock
(
_cache_lock
,
[
&
,
this
](){
...
...
libraries/chain/webassembly/jit.cpp
0 → 100644
浏览文件 @
9a614ead
#include <eosio/chain/webassembly/jit.hpp>
#include <eosio/chain/wasm_eosio_constraints.hpp>
#include "IR/Module.h"
#include "Platform/Platform.h"
#include "WAST/WAST.h"
#include "IR/Operators.h"
#include "IR/Validate.h"
#include "Runtime/Linker.h"
#include "Runtime/Intrinsics.h"
using
namespace
IR
;
using
namespace
Runtime
;
namespace
eosio
{
namespace
chain
{
namespace
webassembly
{
namespace
jit
{
/**
* Integration with the WASM Linker to resolve our intrinsics
*/
struct
root_resolver
:
Runtime
::
Resolver
{
bool
resolve
(
const
string
&
mod_name
,
const
string
&
export_name
,
ObjectType
type
,
ObjectInstance
*&
out
)
override
{
try
{
// Try to resolve an intrinsic first.
if
(
IntrinsicResolver
::
singleton
.
resolve
(
mod_name
,
export_name
,
type
,
out
))
{
return
true
;
}
FC_ASSERT
(
!
"unresolvable"
,
"${module}.${export}"
,
(
"module"
,
mod_name
)(
"export"
,
export_name
)
);
return
false
;
}
FC_CAPTURE_AND_RETHROW
(
(
mod_name
)(
export_name
)
)
}
};
void
entry
::
reset
(
const
info
&
base_info
)
{
if
(
getDefaultMemory
(
instance
))
{
char
*
memstart
=
&
memoryRef
<
char
>
(
getDefaultMemory
(
instance
),
0
);
memset
(
memstart
+
base_info
.
mem_end
,
0
,
((
1
<<
16
)
-
base_info
.
mem_end
)
);
memcpy
(
memstart
,
base_info
.
mem_image
.
data
(),
base_info
.
mem_end
);
}
resetGlobalInstances
(
instance
);
}
entry
entry
::
build
(
const
char
*
wasm_binary
,
size_t
wasm_binary_size
)
{
Module
*
module
=
new
Module
();
Serialization
::
MemoryInputStream
stream
((
const
U8
*
)
wasm_binary
,
wasm_binary_size
);
WASM
::
serializeWithInjection
(
stream
,
*
module
);
validate_eosio_wasm_constraints
(
*
module
);
root_resolver
resolver
;
LinkResult
link_result
=
linkModule
(
*
module
,
resolver
);
ModuleInstance
*
instance
=
instantiateModule
(
*
module
,
std
::
move
(
link_result
.
resolvedImports
));
FC_ASSERT
(
instance
!=
nullptr
);
return
entry
(
instance
,
module
);
};
}}}}
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录