mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 18:32:23 +00:00
vendor: Add EVMC 5.2.0
govendor fetch github.com/ethereum/evmc/bindings/go/evmc@=v5.2.0
This commit is contained in:
parent
cdf5982cfc
commit
33bf2f9da2
9 changed files with 2040 additions and 0 deletions
202
vendor/github.com/ethereum/evmc/LICENSE
generated
vendored
Normal file
202
vendor/github.com/ethereum/evmc/LICENSE
generated
vendored
Normal file
|
|
@ -0,0 +1,202 @@
|
||||||
|
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
279
vendor/github.com/ethereum/evmc/bindings/go/evmc/evmc.go
generated
vendored
Normal file
279
vendor/github.com/ethereum/evmc/bindings/go/evmc/evmc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,279 @@
|
||||||
|
// EVMC: Ethereum Client-VM Connector API.
|
||||||
|
// Copyright 2018 The EVMC Authors.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See the LICENSE file.
|
||||||
|
|
||||||
|
package evmc
|
||||||
|
|
||||||
|
/*
|
||||||
|
#cgo CFLAGS: -I${SRCDIR}/.. -Wall -Wextra
|
||||||
|
#cgo !windows LDFLAGS: -ldl
|
||||||
|
|
||||||
|
#include <evmc/evmc.h>
|
||||||
|
#include <evmc/helpers.h>
|
||||||
|
#include <evmc/loader.h>
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
static inline int set_option(struct evmc_instance* instance, char* name, char* value)
|
||||||
|
{
|
||||||
|
int ret = evmc_set_option(instance, name, value);
|
||||||
|
free(name);
|
||||||
|
free(value);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct extended_context
|
||||||
|
{
|
||||||
|
struct evmc_context context;
|
||||||
|
int64_t index;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern const struct evmc_context_fn_table evmc_go_fn_table;
|
||||||
|
|
||||||
|
static struct evmc_result execute_wrapper(struct evmc_instance* instance, int64_t context_index, enum evmc_revision rev,
|
||||||
|
const struct evmc_address* destination, const struct evmc_address* sender, const struct evmc_uint256be* value,
|
||||||
|
const uint8_t* input_data, size_t input_size, const struct evmc_uint256be* code_hash, int64_t gas,
|
||||||
|
int32_t depth, enum evmc_call_kind kind, uint32_t flags, const uint8_t* code, size_t code_size)
|
||||||
|
{
|
||||||
|
struct evmc_uint256be create2_salt = {};
|
||||||
|
struct evmc_message msg = {
|
||||||
|
*destination,
|
||||||
|
*sender,
|
||||||
|
*value,
|
||||||
|
input_data,
|
||||||
|
input_size,
|
||||||
|
*code_hash,
|
||||||
|
create2_salt,
|
||||||
|
gas,
|
||||||
|
depth,
|
||||||
|
kind,
|
||||||
|
flags,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct extended_context ctx = {{&evmc_go_fn_table}, context_index};
|
||||||
|
return evmc_execute(instance, &ctx.context, rev, &msg, code, code_size);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"sync"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Static asserts.
|
||||||
|
const (
|
||||||
|
_ = uint(common.HashLength - C.sizeof_struct_evmc_uint256be) // The size of evmc_uint256be equals the size of Hash.
|
||||||
|
_ = uint(C.sizeof_struct_evmc_uint256be - common.HashLength)
|
||||||
|
_ = uint(common.AddressLength - C.sizeof_struct_evmc_address) // The size of evmc_address equals the size of Address.
|
||||||
|
_ = uint(C.sizeof_struct_evmc_address - common.AddressLength)
|
||||||
|
)
|
||||||
|
|
||||||
|
type Error int32
|
||||||
|
|
||||||
|
func (err Error) IsInternalError() bool {
|
||||||
|
return err < 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (err Error) Error() string {
|
||||||
|
code := C.enum_evmc_status_code(err)
|
||||||
|
|
||||||
|
switch code {
|
||||||
|
case C.EVMC_FAILURE:
|
||||||
|
return "evmc: failure"
|
||||||
|
case C.EVMC_REVERT:
|
||||||
|
return "evmc: revert"
|
||||||
|
case C.EVMC_OUT_OF_GAS:
|
||||||
|
return "evmc: out of gas"
|
||||||
|
case C.EVMC_INVALID_INSTRUCTION:
|
||||||
|
return "evmc: invalid instruction"
|
||||||
|
case C.EVMC_UNDEFINED_INSTRUCTION:
|
||||||
|
return "evmc: undefined instruction"
|
||||||
|
case C.EVMC_STACK_OVERFLOW:
|
||||||
|
return "evmc: stack overflow"
|
||||||
|
case C.EVMC_STACK_UNDERFLOW:
|
||||||
|
return "evmc: stack underflow"
|
||||||
|
case C.EVMC_BAD_JUMP_DESTINATION:
|
||||||
|
return "evmc: bad jump destination"
|
||||||
|
case C.EVMC_INVALID_MEMORY_ACCESS:
|
||||||
|
return "evmc: invalid memory access"
|
||||||
|
case C.EVMC_CALL_DEPTH_EXCEEDED:
|
||||||
|
return "evmc: call depth exceeded"
|
||||||
|
case C.EVMC_STATIC_MODE_VIOLATION:
|
||||||
|
return "evmc: static mode violation"
|
||||||
|
case C.EVMC_PRECOMPILE_FAILURE:
|
||||||
|
return "evmc: precompile failure"
|
||||||
|
case C.EVMC_CONTRACT_VALIDATION_FAILURE:
|
||||||
|
return "evmc: contract validation failure"
|
||||||
|
case C.EVMC_ARGUMENT_OUT_OF_RANGE:
|
||||||
|
return "evmc: argument out of range"
|
||||||
|
case C.EVMC_WASM_UNREACHABLE_INSTRUCTION:
|
||||||
|
return "evmc: the WebAssembly unreachable instruction has been hit during execution"
|
||||||
|
case C.EVMC_WASM_TRAP:
|
||||||
|
return "evmc: a WebAssembly trap has been hit during execution"
|
||||||
|
case C.EVMC_REJECTED:
|
||||||
|
return "evmc: rejected"
|
||||||
|
}
|
||||||
|
|
||||||
|
if code < 0 {
|
||||||
|
return fmt.Sprintf("evmc: internal error (%d)", int32(code))
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Sprintf("evmc: unknown non-fatal status code %d", int32(code))
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
Failure = Error(C.EVMC_FAILURE)
|
||||||
|
Revert = Error(C.EVMC_REVERT)
|
||||||
|
)
|
||||||
|
|
||||||
|
type Revision int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
Frontier Revision = C.EVMC_FRONTIER
|
||||||
|
Homestead Revision = C.EVMC_HOMESTEAD
|
||||||
|
TangerineWhistle Revision = C.EVMC_TANGERINE_WHISTLE
|
||||||
|
SpuriousDragon Revision = C.EVMC_SPURIOUS_DRAGON
|
||||||
|
Byzantium Revision = C.EVMC_BYZANTIUM
|
||||||
|
Constantinople Revision = C.EVMC_CONSTANTINOPLE
|
||||||
|
)
|
||||||
|
|
||||||
|
type Instance struct {
|
||||||
|
handle *C.struct_evmc_instance
|
||||||
|
}
|
||||||
|
|
||||||
|
func Load(filename string) (instance *Instance, err error) {
|
||||||
|
cfilename := C.CString(filename)
|
||||||
|
var loaderErr C.enum_evmc_loader_error_code
|
||||||
|
handle := C.evmc_load_and_create(cfilename, &loaderErr)
|
||||||
|
C.free(unsafe.Pointer(cfilename))
|
||||||
|
switch loaderErr {
|
||||||
|
case C.EVMC_LOADER_SUCCESS:
|
||||||
|
instance = &Instance{handle}
|
||||||
|
case C.EVMC_LOADER_CANNOT_OPEN:
|
||||||
|
err = fmt.Errorf("evmc loader: cannot open %s", filename)
|
||||||
|
case C.EVMC_LOADER_SYMBOL_NOT_FOUND:
|
||||||
|
err = fmt.Errorf("evmc loader: the EVMC create function not found in %s", filename)
|
||||||
|
case C.EVMC_LOADER_INVALID_ARGUMENT:
|
||||||
|
panic("evmc loader: filename argument is invalid")
|
||||||
|
case C.EVMC_LOADER_INSTANCE_CREATION_FAILURE:
|
||||||
|
err = errors.New("evmc loader: VM instance creation failure")
|
||||||
|
case C.EVMC_LOADER_ABI_VERSION_MISMATCH:
|
||||||
|
err = errors.New("evmc loader: ABI version mismatch")
|
||||||
|
default:
|
||||||
|
panic(fmt.Sprintf("evmc loader: unexpected error (%d)", int(loaderErr)))
|
||||||
|
}
|
||||||
|
return instance, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (instance *Instance) Destroy() {
|
||||||
|
C.evmc_destroy(instance.handle)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (instance *Instance) Name() string {
|
||||||
|
// TODO: consider using C.evmc_vm_name(instance.handle)
|
||||||
|
return C.GoString(instance.handle.name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (instance *Instance) Version() string {
|
||||||
|
// TODO: consider using C.evmc_vm_version(instance.handle)
|
||||||
|
return C.GoString(instance.handle.version)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (instance *Instance) SetOption(name string, value string) (err error) {
|
||||||
|
|
||||||
|
r := C.set_option(instance.handle, C.CString(name), C.CString(value))
|
||||||
|
if r != 1 {
|
||||||
|
err = fmt.Errorf("evmc: option '%s' not accepted", name)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (instance *Instance) Execute(ctx HostContext, rev Revision,
|
||||||
|
destination common.Address, sender common.Address, value common.Hash, input []byte, codeHash common.Hash, gas int64,
|
||||||
|
depth int, kind CallKind, static bool, code []byte) (output []byte, gasLeft int64, err error) {
|
||||||
|
|
||||||
|
flags := C.uint32_t(0)
|
||||||
|
if static {
|
||||||
|
flags |= C.EVMC_STATIC
|
||||||
|
}
|
||||||
|
|
||||||
|
ctxId := addHostContext(ctx)
|
||||||
|
// FIXME: Clarify passing by pointer vs passing by value.
|
||||||
|
evmcDestination := evmcAddress(destination)
|
||||||
|
evmcSender := evmcAddress(sender)
|
||||||
|
evmcValue := evmcUint256be(value)
|
||||||
|
evmcCodeHash := evmcUint256be(codeHash)
|
||||||
|
result := C.execute_wrapper(instance.handle, C.int64_t(ctxId), uint32(rev), &evmcDestination, &evmcSender, &evmcValue,
|
||||||
|
bytesPtr(input), C.size_t(len(input)), &evmcCodeHash, C.int64_t(gas), C.int32_t(depth), C.enum_evmc_call_kind(kind),
|
||||||
|
flags, bytesPtr(code), C.size_t(len(code)))
|
||||||
|
removeHostContext(ctxId)
|
||||||
|
|
||||||
|
output = C.GoBytes(unsafe.Pointer(result.output_data), C.int(result.output_size))
|
||||||
|
gasLeft = int64(result.gas_left)
|
||||||
|
if result.status_code != C.EVMC_SUCCESS {
|
||||||
|
err = Error(result.status_code)
|
||||||
|
}
|
||||||
|
|
||||||
|
if result.release != nil {
|
||||||
|
C.evmc_release_result(&result)
|
||||||
|
}
|
||||||
|
|
||||||
|
return output, gasLeft, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
hostContextCounter int
|
||||||
|
hostContextMap = map[int]HostContext{}
|
||||||
|
hostContextMapMu sync.Mutex
|
||||||
|
)
|
||||||
|
|
||||||
|
func addHostContext(ctx HostContext) int {
|
||||||
|
hostContextMapMu.Lock()
|
||||||
|
id := hostContextCounter
|
||||||
|
hostContextCounter++
|
||||||
|
hostContextMap[id] = ctx
|
||||||
|
hostContextMapMu.Unlock()
|
||||||
|
return id
|
||||||
|
}
|
||||||
|
|
||||||
|
func removeHostContext(id int) {
|
||||||
|
hostContextMapMu.Lock()
|
||||||
|
delete(hostContextMap, id)
|
||||||
|
hostContextMapMu.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
func getHostContext(idx int) HostContext {
|
||||||
|
hostContextMapMu.Lock()
|
||||||
|
ctx := hostContextMap[idx]
|
||||||
|
hostContextMapMu.Unlock()
|
||||||
|
return ctx
|
||||||
|
}
|
||||||
|
|
||||||
|
func evmcUint256be(in common.Hash) C.struct_evmc_uint256be {
|
||||||
|
out := C.struct_evmc_uint256be{}
|
||||||
|
for i := 0; i < len(in); i++ {
|
||||||
|
out.bytes[i] = C.uint8_t(in[i])
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
func evmcAddress(address common.Address) C.struct_evmc_address {
|
||||||
|
r := C.struct_evmc_address{}
|
||||||
|
for i := 0; i < len(address); i++ {
|
||||||
|
r.bytes[i] = C.uint8_t(address[i])
|
||||||
|
}
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func bytesPtr(bytes []byte) *C.uint8_t {
|
||||||
|
if len(bytes) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return (*C.uint8_t)(unsafe.Pointer(&bytes[0]))
|
||||||
|
}
|
||||||
868
vendor/github.com/ethereum/evmc/bindings/go/evmc/evmc.h
generated
vendored
Normal file
868
vendor/github.com/ethereum/evmc/bindings/go/evmc/evmc.h
generated
vendored
Normal file
|
|
@ -0,0 +1,868 @@
|
||||||
|
/**
|
||||||
|
* EVMC: Ethereum Client-VM Connector API
|
||||||
|
*
|
||||||
|
* @copyright
|
||||||
|
* Copyright 2018 The EVMC Authors.
|
||||||
|
* Licensed under the Apache License, Version 2.0. See the LICENSE file.
|
||||||
|
*
|
||||||
|
* @defgroup EVMC EVMC
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#ifndef EVMC_H
|
||||||
|
#define EVMC_H
|
||||||
|
|
||||||
|
#include <stddef.h> /* Definition of size_t. */
|
||||||
|
#include <stdint.h> /* Definition of int64_t, uint64_t. */
|
||||||
|
|
||||||
|
#if __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* BEGIN Python CFFI declarations */
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
/** The EVMC ABI version number of the interface declared in this file. */
|
||||||
|
EVMC_ABI_VERSION = 5
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Big-endian 256-bit integer.
|
||||||
|
*
|
||||||
|
* 32 bytes of data representing big-endian 256-bit integer. I.e. bytes[0] is
|
||||||
|
* the most significant byte, bytes[31] is the least significant byte.
|
||||||
|
* This type is used to transfer to/from the VM values interpreted by the user
|
||||||
|
* as both 256-bit integers and 256-bit hashes.
|
||||||
|
*/
|
||||||
|
struct evmc_uint256be
|
||||||
|
{
|
||||||
|
/** The 32 bytes of the big-endian integer or hash. */
|
||||||
|
uint8_t bytes[32];
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Big-endian 160-bit hash suitable for keeping an Ethereum address. */
|
||||||
|
struct evmc_address
|
||||||
|
{
|
||||||
|
/** The 20 bytes of the hash. */
|
||||||
|
uint8_t bytes[20];
|
||||||
|
};
|
||||||
|
|
||||||
|
/** The kind of call-like instruction. */
|
||||||
|
enum evmc_call_kind
|
||||||
|
{
|
||||||
|
EVMC_CALL = 0, /**< Request CALL. */
|
||||||
|
EVMC_DELEGATECALL = 1, /**< Request DELEGATECALL. Valid since Homestead.
|
||||||
|
The value param ignored. */
|
||||||
|
EVMC_CALLCODE = 2, /**< Request CALLCODE. */
|
||||||
|
EVMC_CREATE = 3, /**< Request CREATE. */
|
||||||
|
EVMC_CREATE2 = 4 /**< Request CREATE2. Valid since Constantinople.*/
|
||||||
|
};
|
||||||
|
|
||||||
|
/** The flags for ::evmc_message. */
|
||||||
|
enum evmc_flags
|
||||||
|
{
|
||||||
|
EVMC_STATIC = 1 /**< Static call mode. */
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The message describing an EVM call,
|
||||||
|
* including a zero-depth calls from a transaction origin.
|
||||||
|
*/
|
||||||
|
struct evmc_message
|
||||||
|
{
|
||||||
|
/** The destination of the message. */
|
||||||
|
struct evmc_address destination;
|
||||||
|
|
||||||
|
/** The sender of the message. */
|
||||||
|
struct evmc_address sender;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The amount of Ether transferred with the message.
|
||||||
|
*/
|
||||||
|
struct evmc_uint256be value;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The message input data.
|
||||||
|
*
|
||||||
|
* This MAY be NULL.
|
||||||
|
*/
|
||||||
|
const uint8_t* input_data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The size of the message input data.
|
||||||
|
*
|
||||||
|
* If input_data is NULL this MUST be 0.
|
||||||
|
*/
|
||||||
|
size_t input_size;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The optional hash of the code of the destination account.
|
||||||
|
* The null hash MUST be used when not specified.
|
||||||
|
*/
|
||||||
|
struct evmc_uint256be code_hash;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The optional value used in new contract address construction.
|
||||||
|
*
|
||||||
|
* Ignored unless kind is EVMC_CREATE2.
|
||||||
|
*/
|
||||||
|
struct evmc_uint256be create2_salt;
|
||||||
|
|
||||||
|
/** The amount of gas for message execution. */
|
||||||
|
int64_t gas;
|
||||||
|
|
||||||
|
/** The call depth. */
|
||||||
|
int32_t depth;
|
||||||
|
|
||||||
|
/** The kind of the call. For zero-depth calls ::EVMC_CALL SHOULD be used. */
|
||||||
|
enum evmc_call_kind kind;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Additional flags modifying the call execution behavior.
|
||||||
|
* In the current version the only valid values are ::EVMC_STATIC or 0.
|
||||||
|
*/
|
||||||
|
uint32_t flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/** The transaction and block data for execution. */
|
||||||
|
struct evmc_tx_context
|
||||||
|
{
|
||||||
|
struct evmc_uint256be tx_gas_price; /**< The transaction gas price. */
|
||||||
|
struct evmc_address tx_origin; /**< The transaction origin account. */
|
||||||
|
struct evmc_address block_coinbase; /**< The miner of the block. */
|
||||||
|
int64_t block_number; /**< The block number. */
|
||||||
|
int64_t block_timestamp; /**< The block timestamp. */
|
||||||
|
int64_t block_gas_limit; /**< The block gas limit. */
|
||||||
|
struct evmc_uint256be block_difficulty; /**< The block difficulty. */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct evmc_context;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get transaction context callback function.
|
||||||
|
*
|
||||||
|
* This callback function is used by an EVM to retrieve the transaction and
|
||||||
|
* block context.
|
||||||
|
*
|
||||||
|
* @param[out] result The returned transaction context.
|
||||||
|
* @see ::evmc_tx_context.
|
||||||
|
* @param context The pointer to the Host execution context.
|
||||||
|
* @see ::evmc_context.
|
||||||
|
*/
|
||||||
|
typedef void (*evmc_get_tx_context_fn)(struct evmc_tx_context* result,
|
||||||
|
struct evmc_context* context);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get block hash callback function.
|
||||||
|
*
|
||||||
|
* This callback function is used by an EVM to query the block hash of
|
||||||
|
* a given block.
|
||||||
|
*
|
||||||
|
* @param[out] result The returned block hash value.
|
||||||
|
* @param context The pointer to the Host execution context.
|
||||||
|
* @param number The block number. Must be a value between
|
||||||
|
* (and including) 0 and 255.
|
||||||
|
*/
|
||||||
|
typedef void (*evmc_get_block_hash_fn)(struct evmc_uint256be* result,
|
||||||
|
struct evmc_context* context,
|
||||||
|
int64_t number);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The execution status code.
|
||||||
|
*
|
||||||
|
* Successful execution is represented by ::EVMC_SUCCESS having value 0.
|
||||||
|
*
|
||||||
|
* Positive values represent failures defined by VM specifications with generic
|
||||||
|
* ::EVMC_FAILURE code of value 1.
|
||||||
|
*
|
||||||
|
* Status codes with negative values represent VM internal errors
|
||||||
|
* not provided by EVM specifications. These errors MUST not be passed back
|
||||||
|
* to the caller. They MAY be handled by the Client in predefined manner
|
||||||
|
* (see e.g. ::EVMC_REJECTED), otherwise internal errors are not recoverable.
|
||||||
|
* The generic representant of errors is ::EVMC_INTERNAL_ERROR but
|
||||||
|
* an EVM implementation MAY return negative status codes that are not defined
|
||||||
|
* in the EVMC documentation.
|
||||||
|
*
|
||||||
|
* @note
|
||||||
|
* In case new status codes are needed, please create an issue or pull request
|
||||||
|
* in the EVMC repository (https://github.com/ethereum/evmc).
|
||||||
|
*/
|
||||||
|
enum evmc_status_code
|
||||||
|
{
|
||||||
|
/** Execution finished with success. */
|
||||||
|
EVMC_SUCCESS = 0,
|
||||||
|
|
||||||
|
/** Generic execution failure. */
|
||||||
|
EVMC_FAILURE = 1,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execution terminated with REVERT opcode.
|
||||||
|
*
|
||||||
|
* In this case the amount of gas left MAY be non-zero and additional output
|
||||||
|
* data MAY be provided in ::evmc_result.
|
||||||
|
*/
|
||||||
|
EVMC_REVERT = 2,
|
||||||
|
|
||||||
|
/** The execution has run out of gas. */
|
||||||
|
EVMC_OUT_OF_GAS = 3,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The designated INVALID instruction has been hit during execution.
|
||||||
|
*
|
||||||
|
* The EIP-141 (https://github.com/ethereum/EIPs/blob/master/EIPS/eip-141.md)
|
||||||
|
* defines the instruction 0xfe as INVALID instruction to indicate execution
|
||||||
|
* abortion coming from high-level languages. This status code is reported
|
||||||
|
* in case this INVALID instruction has been encountered.
|
||||||
|
*/
|
||||||
|
EVMC_INVALID_INSTRUCTION = 4,
|
||||||
|
|
||||||
|
/** An undefined instruction has been encountered. */
|
||||||
|
EVMC_UNDEFINED_INSTRUCTION = 5,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The execution has attempted to put more items on the EVM stack
|
||||||
|
* than the specified limit.
|
||||||
|
*/
|
||||||
|
EVMC_STACK_OVERFLOW = 6,
|
||||||
|
|
||||||
|
/** Execution of an opcode has required more items on the EVM stack. */
|
||||||
|
EVMC_STACK_UNDERFLOW = 7,
|
||||||
|
|
||||||
|
/** Execution has violated the jump destination restrictions. */
|
||||||
|
EVMC_BAD_JUMP_DESTINATION = 8,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tried to read outside memory bounds.
|
||||||
|
*
|
||||||
|
* An example is RETURNDATACOPY reading past the available buffer.
|
||||||
|
*/
|
||||||
|
EVMC_INVALID_MEMORY_ACCESS = 9,
|
||||||
|
|
||||||
|
/** Call depth has exceeded the limit (if any) */
|
||||||
|
EVMC_CALL_DEPTH_EXCEEDED = 10,
|
||||||
|
|
||||||
|
/** Tried to execute an operation which is restricted in static mode. */
|
||||||
|
EVMC_STATIC_MODE_VIOLATION = 11,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A call to a precompiled or system contract has ended with a failure.
|
||||||
|
*
|
||||||
|
* An example: elliptic curve functions handed invalid EC points.
|
||||||
|
*/
|
||||||
|
EVMC_PRECOMPILE_FAILURE = 12,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contract validation has failed (e.g. due to EVM 1.5 jump validity,
|
||||||
|
* Casper's purity checker or ewasm contract rules).
|
||||||
|
*/
|
||||||
|
EVMC_CONTRACT_VALIDATION_FAILURE = 13,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An argument to a state accessing method has a value outside of the
|
||||||
|
* accepted range of values.
|
||||||
|
*/
|
||||||
|
EVMC_ARGUMENT_OUT_OF_RANGE = 14,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A WebAssembly `unreachable` instruction has been hit during exection.
|
||||||
|
*/
|
||||||
|
EVMC_WASM_UNREACHABLE_INSTRUCTION = 15,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A WebAssembly trap has been hit during execution. This can be for many
|
||||||
|
* reasons, including division by zero, validation errors, etc.
|
||||||
|
*/
|
||||||
|
EVMC_WASM_TRAP = 16,
|
||||||
|
|
||||||
|
/** EVM implementation generic internal error. */
|
||||||
|
EVMC_INTERNAL_ERROR = -1,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The execution of the given code and/or message has been rejected
|
||||||
|
* by the EVM implementation.
|
||||||
|
*
|
||||||
|
* This error SHOULD be used to signal that the EVM is not able to or
|
||||||
|
* willing to execute the given code type or message.
|
||||||
|
* If an EVM returns the ::EVMC_REJECTED status code,
|
||||||
|
* the Client MAY try to execute it in other EVM implementation.
|
||||||
|
* For example, the Client tries running a code in the EVM 1.5. If the
|
||||||
|
* code is not supported there, the execution falls back to the EVM 1.0.
|
||||||
|
*/
|
||||||
|
EVMC_REJECTED = -2
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Forward declaration. */
|
||||||
|
struct evmc_result;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Releases resources assigned to an execution result.
|
||||||
|
*
|
||||||
|
* This function releases memory (and other resources, if any) assigned to the
|
||||||
|
* specified execution result making the result object invalid.
|
||||||
|
*
|
||||||
|
* @param result The execution result which resources are to be released. The
|
||||||
|
* result itself it not modified by this function, but becomes
|
||||||
|
* invalid and user MUST discard it as well.
|
||||||
|
* This MUST NOT be NULL.
|
||||||
|
*
|
||||||
|
* @note
|
||||||
|
* The result is passed by pointer to avoid (shallow) copy of the ::evmc_result
|
||||||
|
* struct. Think of this as the best possible C language approximation to
|
||||||
|
* passing objects by reference.
|
||||||
|
*/
|
||||||
|
typedef void (*evmc_release_result_fn)(const struct evmc_result* result);
|
||||||
|
|
||||||
|
/** The EVM code execution result. */
|
||||||
|
struct evmc_result
|
||||||
|
{
|
||||||
|
/** The execution status code. */
|
||||||
|
enum evmc_status_code status_code;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The amount of gas left after the execution.
|
||||||
|
*
|
||||||
|
* If evmc_result::code is not ::EVMC_SUCCESS nor ::EVMC_REVERT
|
||||||
|
* the value MUST be 0.
|
||||||
|
*/
|
||||||
|
int64_t gas_left;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The reference to output data.
|
||||||
|
*
|
||||||
|
* The output contains data coming from RETURN opcode (iff evmc_result::code
|
||||||
|
* field is ::EVMC_SUCCESS) or from REVERT opcode.
|
||||||
|
*
|
||||||
|
* The memory containing the output data is owned by EVM and has to be
|
||||||
|
* freed with evmc_result::release().
|
||||||
|
*
|
||||||
|
* This MAY be NULL.
|
||||||
|
*/
|
||||||
|
const uint8_t* output_data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The size of the output data.
|
||||||
|
*
|
||||||
|
* If output_data is NULL this MUST be 0.
|
||||||
|
*/
|
||||||
|
size_t output_size;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The pointer to a function releasing all resources associated with
|
||||||
|
* the result object.
|
||||||
|
*
|
||||||
|
* This function pointer is optional (MAY be NULL) and MAY be set by
|
||||||
|
* the EVM implementation. If set it MUST be used by the user to
|
||||||
|
* release memory and other resources associated with the result object.
|
||||||
|
* After the result resources are released the result object
|
||||||
|
* MUST NOT be used any more.
|
||||||
|
*
|
||||||
|
* The suggested code pattern for releasing EVM results:
|
||||||
|
* @code
|
||||||
|
* struct evmc_result result = ...;
|
||||||
|
* if (result.release)
|
||||||
|
* result.release(&result);
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* @note
|
||||||
|
* It works similarly to C++ virtual destructor. Attaching the release
|
||||||
|
* function to the result itself allows EVM composition.
|
||||||
|
*/
|
||||||
|
evmc_release_result_fn release;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The address of the contract created by CREATE opcode.
|
||||||
|
*
|
||||||
|
* This field has valid value only if the result describes successful
|
||||||
|
* CREATE (evmc_result::status_code is ::EVMC_SUCCESS).
|
||||||
|
*/
|
||||||
|
struct evmc_address create_address;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reserved data that MAY be used by a evmc_result object creator.
|
||||||
|
*
|
||||||
|
* This reserved 4 bytes together with 20 bytes from create_address form
|
||||||
|
* 24 bytes of memory called "optional data" within evmc_result struct
|
||||||
|
* to be optionally used by the evmc_result object creator.
|
||||||
|
*
|
||||||
|
* @see evmc_result_optional_data, evmc_get_optional_data().
|
||||||
|
*
|
||||||
|
* Also extends the size of the evmc_result to 64 bytes (full cache line).
|
||||||
|
*/
|
||||||
|
uint8_t padding[4];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check account existence callback function
|
||||||
|
*
|
||||||
|
* This callback function is used by the EVM to check if
|
||||||
|
* there exists an account at given address.
|
||||||
|
* @param context The pointer to the Host execution context.
|
||||||
|
* @see ::evmc_context.
|
||||||
|
* @param address The address of the account the query is about.
|
||||||
|
* @return 1 if exists, 0 otherwise.
|
||||||
|
*/
|
||||||
|
typedef int (*evmc_account_exists_fn)(struct evmc_context* context,
|
||||||
|
const struct evmc_address* address);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get storage callback function.
|
||||||
|
*
|
||||||
|
* This callback function is used by an EVM to query the given contract
|
||||||
|
* storage entry.
|
||||||
|
* @param[out] result The returned storage value.
|
||||||
|
* @param context The pointer to the Host execution context.
|
||||||
|
* @see ::evmc_context.
|
||||||
|
* @param address The address of the contract.
|
||||||
|
* @param key The index of the storage entry.
|
||||||
|
*/
|
||||||
|
typedef void (*evmc_get_storage_fn)(struct evmc_uint256be* result,
|
||||||
|
struct evmc_context* context,
|
||||||
|
const struct evmc_address* address,
|
||||||
|
const struct evmc_uint256be* key);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The effect of an attempt to modify a contract storage item.
|
||||||
|
*
|
||||||
|
* For the purpose of explaining the meaning of each element, the following
|
||||||
|
* notation is used:
|
||||||
|
* - 0 is zero value,
|
||||||
|
* - X != 0 (X is any value other than 0),
|
||||||
|
* - Y != X, Y != 0 (Y is any value other than X and 0),
|
||||||
|
* - the "->" means the change from one value to another.
|
||||||
|
*/
|
||||||
|
enum evmc_storage_status
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The value of a storage item has been left unchanged: 0 -> 0 and X -> X.
|
||||||
|
*/
|
||||||
|
EVMC_STORAGE_UNCHANGED = 0,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The value of a storage item has been modified: X -> Y.
|
||||||
|
*/
|
||||||
|
EVMC_STORAGE_MODIFIED = 1,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A new storage item has been added: 0 -> X.
|
||||||
|
*/
|
||||||
|
EVMC_STORAGE_ADDED = 2,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A storage item has been deleted: X -> 0.
|
||||||
|
*/
|
||||||
|
EVMC_STORAGE_DELETED = 3
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set storage callback function.
|
||||||
|
*
|
||||||
|
* This callback function is used by an EVM to update the given contract
|
||||||
|
* storage entry.
|
||||||
|
* @param context The pointer to the Host execution context.
|
||||||
|
* @see ::evmc_context.
|
||||||
|
* @param address The address of the contract.
|
||||||
|
* @param key The index of the storage entry.
|
||||||
|
* @param value The value to be stored.
|
||||||
|
* @return The effect on the storage item, @see ::evmc_storage_status.
|
||||||
|
*/
|
||||||
|
typedef enum evmc_storage_status (*evmc_set_storage_fn)(struct evmc_context* context,
|
||||||
|
const struct evmc_address* address,
|
||||||
|
const struct evmc_uint256be* key,
|
||||||
|
const struct evmc_uint256be* value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get balance callback function.
|
||||||
|
*
|
||||||
|
* This callback function is used by an EVM to query the balance of the given
|
||||||
|
* address.
|
||||||
|
* @param[out] result The returned balance value.
|
||||||
|
* @param context The pointer to the Host execution context.
|
||||||
|
* @see ::evmc_context.
|
||||||
|
* @param address The address.
|
||||||
|
*/
|
||||||
|
typedef void (*evmc_get_balance_fn)(struct evmc_uint256be* result,
|
||||||
|
struct evmc_context* context,
|
||||||
|
const struct evmc_address* address);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get code size callback function.
|
||||||
|
*
|
||||||
|
* This callback function is used by an EVM to get the size of the code stored
|
||||||
|
* in the account at the given address. For accounts not having a code, this
|
||||||
|
* function returns 0.
|
||||||
|
*/
|
||||||
|
typedef size_t (*evmc_get_code_size_fn)(struct evmc_context* context,
|
||||||
|
const struct evmc_address* address);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get code size callback function.
|
||||||
|
*
|
||||||
|
* This callback function is used by an EVM to get the keccak256 hash of the code stored
|
||||||
|
* in the account at the given address. For accounts not having a code, this
|
||||||
|
* function returns keccak256 hash of empty data. For accounts not existing in the state,
|
||||||
|
* this function returns 0.
|
||||||
|
*/
|
||||||
|
typedef void (*evmc_get_code_hash_fn)(struct evmc_uint256be* result,
|
||||||
|
struct evmc_context* context,
|
||||||
|
const struct evmc_address* address);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy code callback function.
|
||||||
|
*
|
||||||
|
* This callback function is used by an EVM to request a copy of the code
|
||||||
|
* of the given account to the memory buffer provided by the EVM.
|
||||||
|
* The Client MUST copy the requested code, starting with the given offset,
|
||||||
|
* to the provided memory buffer up to the size of the buffer or the size of
|
||||||
|
* the code, whichever is smaller.
|
||||||
|
*
|
||||||
|
* @param context The pointer to the Client execution context.
|
||||||
|
* @see ::evmc_context.
|
||||||
|
* @param address The address of the account.
|
||||||
|
* @param code_offset The offset of the code to copy.
|
||||||
|
* @param buffer_data The pointer to the memory buffer allocated by the EVM
|
||||||
|
* to store a copy of the requested code.
|
||||||
|
* @param buffer_size The size of the memory buffer.
|
||||||
|
* @return The number of bytes copied to the buffer by the Client.
|
||||||
|
*/
|
||||||
|
typedef size_t (*evmc_copy_code_fn)(struct evmc_context* context,
|
||||||
|
const struct evmc_address* address,
|
||||||
|
size_t code_offset,
|
||||||
|
uint8_t* buffer_data,
|
||||||
|
size_t buffer_size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Selfdestruct callback function.
|
||||||
|
*
|
||||||
|
* This callback function is used by an EVM to SELFDESTRUCT given contract.
|
||||||
|
* The execution of the contract will not be stopped, that is up to the EVM.
|
||||||
|
*
|
||||||
|
* @param context The pointer to the Host execution context.
|
||||||
|
* @see ::evmc_context.
|
||||||
|
* @param address The address of the contract to be selfdestructed.
|
||||||
|
* @param beneficiary The address where the remaining ETH is going to be
|
||||||
|
* transferred.
|
||||||
|
*/
|
||||||
|
typedef void (*evmc_selfdestruct_fn)(struct evmc_context* context,
|
||||||
|
const struct evmc_address* address,
|
||||||
|
const struct evmc_address* beneficiary);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log callback function.
|
||||||
|
*
|
||||||
|
* This callback function is used by an EVM to inform about a LOG that happened
|
||||||
|
* during an EVM bytecode execution.
|
||||||
|
* @param context The pointer to the Host execution context.
|
||||||
|
* @see ::evmc_context.
|
||||||
|
* @param address The address of the contract that generated the log.
|
||||||
|
* @param data The pointer to unindexed data attached to the log.
|
||||||
|
* @param data_size The length of the data.
|
||||||
|
* @param topics The pointer to the array of topics attached to the log.
|
||||||
|
* @param topics_count The number of the topics. Valid values are between
|
||||||
|
* 0 and 4 inclusively.
|
||||||
|
*/
|
||||||
|
typedef void (*evmc_emit_log_fn)(struct evmc_context* context,
|
||||||
|
const struct evmc_address* address,
|
||||||
|
const uint8_t* data,
|
||||||
|
size_t data_size,
|
||||||
|
const struct evmc_uint256be topics[],
|
||||||
|
size_t topics_count);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pointer to the callback function supporting EVM calls.
|
||||||
|
*
|
||||||
|
* @param[out] result The result of the call. The result object is not
|
||||||
|
* initialized by the EVM, the Client MUST correctly
|
||||||
|
* initialize all expected fields of the structure.
|
||||||
|
* @param context The pointer to the Host execution context.
|
||||||
|
* @see ::evmc_context.
|
||||||
|
* @param msg Call parameters. @see ::evmc_message.
|
||||||
|
*/
|
||||||
|
typedef void (*evmc_call_fn)(struct evmc_result* result,
|
||||||
|
struct evmc_context* context,
|
||||||
|
const struct evmc_message* msg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The context interface.
|
||||||
|
*
|
||||||
|
* The set of all callback functions expected by EVM instances. This is C
|
||||||
|
* realisation of vtable for OOP interface (only virtual methods, no data).
|
||||||
|
* Host implementations SHOULD create constant singletons of this (similarly
|
||||||
|
* to vtables) to lower the maintenance and memory management cost.
|
||||||
|
*/
|
||||||
|
struct evmc_context_fn_table
|
||||||
|
{
|
||||||
|
/** Check account existence callback function. */
|
||||||
|
evmc_account_exists_fn account_exists;
|
||||||
|
|
||||||
|
/** Get storage callback function. */
|
||||||
|
evmc_get_storage_fn get_storage;
|
||||||
|
|
||||||
|
/** Set storage callback function. */
|
||||||
|
evmc_set_storage_fn set_storage;
|
||||||
|
|
||||||
|
/** Get balance callback function. */
|
||||||
|
evmc_get_balance_fn get_balance;
|
||||||
|
|
||||||
|
/** Get code size callback function. */
|
||||||
|
evmc_get_code_size_fn get_code_size;
|
||||||
|
|
||||||
|
/** Get code hash callback function. */
|
||||||
|
evmc_get_code_hash_fn get_code_hash;
|
||||||
|
|
||||||
|
/** Copy code callback function. */
|
||||||
|
evmc_copy_code_fn copy_code;
|
||||||
|
|
||||||
|
/** Selfdestruct callback function. */
|
||||||
|
evmc_selfdestruct_fn selfdestruct;
|
||||||
|
|
||||||
|
/** Call callback function. */
|
||||||
|
evmc_call_fn call;
|
||||||
|
|
||||||
|
/** Get transaction context callback function. */
|
||||||
|
evmc_get_tx_context_fn get_tx_context;
|
||||||
|
|
||||||
|
/** Get block hash callback function. */
|
||||||
|
evmc_get_block_hash_fn get_block_hash;
|
||||||
|
|
||||||
|
/** Emit log callback function. */
|
||||||
|
evmc_emit_log_fn emit_log;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execution context managed by the Host.
|
||||||
|
*
|
||||||
|
* The Host MUST pass the pointer to the execution context to
|
||||||
|
* ::evmc_execute_fn. The EVM MUST pass the same pointer back to the Host in
|
||||||
|
* every callback function.
|
||||||
|
* The context MUST contain at least the function table defining the context
|
||||||
|
* callback interface.
|
||||||
|
* Optionally, The Host MAY include in the context additional data.
|
||||||
|
*/
|
||||||
|
struct evmc_context
|
||||||
|
{
|
||||||
|
/** Function table defining the context interface (vtable). */
|
||||||
|
const struct evmc_context_fn_table* fn_table;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Forward declaration. */
|
||||||
|
struct evmc_instance;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroys the EVM instance.
|
||||||
|
*
|
||||||
|
* @param evm The EVM instance to be destroyed.
|
||||||
|
*/
|
||||||
|
typedef void (*evmc_destroy_fn)(struct evmc_instance* evm);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures the EVM instance.
|
||||||
|
*
|
||||||
|
* Allows modifying options of the EVM instance.
|
||||||
|
* Options:
|
||||||
|
* - code cache behavior: on, off, read-only, ...
|
||||||
|
* - optimizations,
|
||||||
|
*
|
||||||
|
* @param evm The EVM instance to be configured.
|
||||||
|
* @param name The option name. NULL-terminated string. Cannot be NULL.
|
||||||
|
* @param value The new option value. NULL-terminated string. Cannot be NULL.
|
||||||
|
* @return 1 if the option set successfully, 0 otherwise.
|
||||||
|
*/
|
||||||
|
typedef int (*evmc_set_option_fn)(struct evmc_instance* evm, char const* name, char const* value);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EVM revision.
|
||||||
|
*
|
||||||
|
* The revision of the EVM specification based on the Ethereum
|
||||||
|
* upgrade / hard fork codenames.
|
||||||
|
*/
|
||||||
|
enum evmc_revision
|
||||||
|
{
|
||||||
|
EVMC_FRONTIER = 0,
|
||||||
|
EVMC_HOMESTEAD = 1,
|
||||||
|
EVMC_TANGERINE_WHISTLE = 2,
|
||||||
|
EVMC_SPURIOUS_DRAGON = 3,
|
||||||
|
EVMC_BYZANTIUM = 4,
|
||||||
|
EVMC_CONSTANTINOPLE = 5,
|
||||||
|
|
||||||
|
EVMC_LATEST_REVISION = EVMC_CONSTANTINOPLE
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes the given EVM bytecode using the input in the message
|
||||||
|
*
|
||||||
|
* This function MAY be invoked multiple times for a single EVM instance.
|
||||||
|
*
|
||||||
|
* @param instance The EVM instance.
|
||||||
|
* @param context The pointer to the Client execution context to be passed
|
||||||
|
* to the callback functions. @see ::evmc_context.
|
||||||
|
* @param rev Requested EVM specification revision.
|
||||||
|
* @param msg Call parameters. @see ::evmc_message.
|
||||||
|
* @param code Reference to the bytecode to be executed.
|
||||||
|
* @param code_size The length of the bytecode.
|
||||||
|
* @return All execution results.
|
||||||
|
*/
|
||||||
|
typedef struct evmc_result (*evmc_execute_fn)(struct evmc_instance* instance,
|
||||||
|
struct evmc_context* context,
|
||||||
|
enum evmc_revision rev,
|
||||||
|
const struct evmc_message* msg,
|
||||||
|
uint8_t const* code,
|
||||||
|
size_t code_size);
|
||||||
|
|
||||||
|
|
||||||
|
/** The opaque type representing a Client-side tracer object. */
|
||||||
|
struct evmc_tracer_context;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The callback to trace instructions execution in an EVM.
|
||||||
|
*
|
||||||
|
* This function informs the Client what instruction has been executed in the EVM implementation
|
||||||
|
* and what are the results of executing this particular instruction.
|
||||||
|
* The message level information (like call depth, destination address, etc.) are not provided here.
|
||||||
|
* This piece of information can be acquired by inspecting messages being sent to the EVM in
|
||||||
|
* ::evmc_execute_fn and the results of the messages execution.
|
||||||
|
*
|
||||||
|
* @param context The pointer to the Client-side tracing context. This allows to
|
||||||
|
* implement the tracer in OOP manner.
|
||||||
|
* @param code_offset The current instruction position in the code.
|
||||||
|
* @param status_code The status code of the instruction execution.
|
||||||
|
* @param gas_left The amount of the gas left after the instruction execution.
|
||||||
|
* @param stack_num_items The current EVM stack height after the instruction execution.
|
||||||
|
* @param pushed_stack_item The top EVM stack item pushed as the result of the instruction
|
||||||
|
* execution. This value is null when the instruction does not push
|
||||||
|
* anything to the stack.
|
||||||
|
* @param memory_size The size of the EVM memory after the instruction execution.
|
||||||
|
* @param changed_memory_offset The offset in number of bytes of the beginning of the memory area
|
||||||
|
* modified as the result of the instruction execution.
|
||||||
|
* The Client MAY use this information together with
|
||||||
|
* @p changed_memory_size and @p changed_memory to incrementally
|
||||||
|
* update the copy of the full VM's memory.
|
||||||
|
* @param changed_memory_size The size of the memory area modified as the result of
|
||||||
|
* the instruction execution.
|
||||||
|
* @param changed_memory The pointer to the memory area modified as the result of
|
||||||
|
* the instruction execution.
|
||||||
|
* The Client MAY access the pointed memory area
|
||||||
|
* (limited by the @p changed_memory_size) only during the current
|
||||||
|
* execution of the evmc_trace_callback().
|
||||||
|
* The pointer MUST NOT be stored by the Client.
|
||||||
|
* The Client MUST NOT assume that
|
||||||
|
* `changed_memory - changed_memory_offset` is a valid base pointer
|
||||||
|
* of the VM memory.
|
||||||
|
*/
|
||||||
|
typedef void (*evmc_trace_callback)(struct evmc_tracer_context* context,
|
||||||
|
size_t code_offset,
|
||||||
|
enum evmc_status_code status_code,
|
||||||
|
int64_t gas_left,
|
||||||
|
size_t stack_num_items,
|
||||||
|
const struct evmc_uint256be* pushed_stack_item,
|
||||||
|
size_t memory_size,
|
||||||
|
size_t changed_memory_offset,
|
||||||
|
size_t changed_memory_size,
|
||||||
|
const uint8_t* changed_memory);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the EVM instruction tracer.
|
||||||
|
*
|
||||||
|
* When the tracer is set in the EVM instance, the EVM SHOULD call back the tracer with information
|
||||||
|
* about instructions execution in the EVM.
|
||||||
|
* @see ::evmc_trace_callback.
|
||||||
|
*
|
||||||
|
* This will overwrite the previous settings (the callback and the context).
|
||||||
|
*
|
||||||
|
* @param instance The EVM instance.
|
||||||
|
* @param callback The tracer callback function. This argument MAY be NULL to disable previously
|
||||||
|
* set tracer.
|
||||||
|
* @param context The Client-side tracer context. This argument MAY be NULL in case the tracer
|
||||||
|
* does not require any context. This argument MUST be NULL if the callback
|
||||||
|
* argument is NULL.
|
||||||
|
*/
|
||||||
|
typedef void (*evmc_set_tracer_fn)(struct evmc_instance* instance,
|
||||||
|
evmc_trace_callback callback,
|
||||||
|
struct evmc_tracer_context* context);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The EVM instance.
|
||||||
|
*
|
||||||
|
* Defines the base struct of the EVM implementation.
|
||||||
|
*/
|
||||||
|
struct evmc_instance
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* EVMC ABI version implemented by the EVM instance.
|
||||||
|
*
|
||||||
|
* Used to detect ABI incompatibilities. The EVMC ABI version
|
||||||
|
* represented by this file is in ::EVMC_ABI_VERSION.
|
||||||
|
*/
|
||||||
|
const int abi_version;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the EVMC VM implementation.
|
||||||
|
*
|
||||||
|
* It MUST be a NULL-terminated not empty string.
|
||||||
|
*/
|
||||||
|
const char* name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The version of the EVMC VM implementation, e.g. "1.2.3b4".
|
||||||
|
*
|
||||||
|
* It MUST be a NULL-terminated not empty string.
|
||||||
|
*/
|
||||||
|
const char* version;
|
||||||
|
|
||||||
|
/** Pointer to function destroying the EVM instance. */
|
||||||
|
evmc_destroy_fn destroy;
|
||||||
|
|
||||||
|
/** Pointer to function executing a code by the EVM instance. */
|
||||||
|
evmc_execute_fn execute;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optional pointer to function setting the EVM instruction tracer.
|
||||||
|
*
|
||||||
|
* If the EVM does not support this feature the pointer can be NULL.
|
||||||
|
*/
|
||||||
|
evmc_set_tracer_fn set_tracer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optional pointer to function modifying VM's options.
|
||||||
|
*
|
||||||
|
* If the VM does not support this feature the pointer can be NULL.
|
||||||
|
*/
|
||||||
|
evmc_set_option_fn set_option;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* END Python CFFI declarations */
|
||||||
|
|
||||||
|
#if EVMC_DOCUMENTATION
|
||||||
|
/**
|
||||||
|
* Example of a function creating an instance of an example EVM implementation.
|
||||||
|
*
|
||||||
|
* Each EVM implementation MUST provide a function returning an EVM instance.
|
||||||
|
* The function SHOULD be named `evmc_create_<vm-name>(void)`. If the VM name contains hyphens
|
||||||
|
* replaces them with underscores in the function names.
|
||||||
|
*
|
||||||
|
* @par Binaries naming convention
|
||||||
|
* For VMs distributed as shared libraries, the name of the library SHOULD match the VM name.
|
||||||
|
* The convetional library filename prefixes and extensions SHOULD be ignored by the Client.
|
||||||
|
* For example, the shared library with the "beta-interpreter" implementation may be named
|
||||||
|
* `libbeta-interpreter.so`.
|
||||||
|
*
|
||||||
|
* @return EVM instance or NULL indicating instance creation failure.
|
||||||
|
*/
|
||||||
|
struct evmc_instance* evmc_create_examplevm(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
/** @} */
|
||||||
155
vendor/github.com/ethereum/evmc/bindings/go/evmc/helpers.h
generated
vendored
Normal file
155
vendor/github.com/ethereum/evmc/bindings/go/evmc/helpers.h
generated
vendored
Normal file
|
|
@ -0,0 +1,155 @@
|
||||||
|
/* EVMC: Ethereum Client-VM Connector API.
|
||||||
|
* Copyright 2018 The EVMC Authors.
|
||||||
|
* Licensed under the Apache License, Version 2.0. See the LICENSE file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EVMC Helpers
|
||||||
|
*
|
||||||
|
* A collection of helper functions for invoking a VM instance methods.
|
||||||
|
* These are convenient for languages where invoking function pointers
|
||||||
|
* is "ugly" or impossible (such as Go).
|
||||||
|
*
|
||||||
|
* @defgroup helpers EVMC Helpers
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <evmc/evmc.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the VM instance has a compatible ABI version.
|
||||||
|
*/
|
||||||
|
static inline int evmc_is_abi_compatible(struct evmc_instance* instance)
|
||||||
|
{
|
||||||
|
return instance->abi_version == EVMC_ABI_VERSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the name of the VM instance.
|
||||||
|
*/
|
||||||
|
static inline const char* evmc_vm_name(struct evmc_instance* instance)
|
||||||
|
{
|
||||||
|
return instance->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the version of the VM instance.
|
||||||
|
*/
|
||||||
|
static inline const char* evmc_vm_version(struct evmc_instance* instance)
|
||||||
|
{
|
||||||
|
return instance->version;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroys the VM instance.
|
||||||
|
*
|
||||||
|
* @see evmc_destroy_fn
|
||||||
|
*/
|
||||||
|
static inline void evmc_destroy(struct evmc_instance* instance)
|
||||||
|
{
|
||||||
|
instance->destroy(instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the option for the VM instance, if the feature is supported by the VM.
|
||||||
|
*
|
||||||
|
* @see evmc_set_option_fn
|
||||||
|
*/
|
||||||
|
static inline int evmc_set_option(struct evmc_instance* instance,
|
||||||
|
char const* name,
|
||||||
|
char const* value)
|
||||||
|
{
|
||||||
|
if (instance->set_option)
|
||||||
|
return instance->set_option(instance, name, value);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the tracer callback for the VM instance, if the feature is supported by the VM.
|
||||||
|
*
|
||||||
|
* @see evmc_set_tracer_fn
|
||||||
|
*/
|
||||||
|
static inline void evmc_set_tracer(struct evmc_instance* instance,
|
||||||
|
evmc_trace_callback callback,
|
||||||
|
struct evmc_tracer_context* context)
|
||||||
|
{
|
||||||
|
if (instance->set_tracer)
|
||||||
|
instance->set_tracer(instance, callback, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes code in the VM instance.
|
||||||
|
*
|
||||||
|
* @see evmc_execute_fn.
|
||||||
|
*/
|
||||||
|
static inline struct evmc_result evmc_execute(struct evmc_instance* instance,
|
||||||
|
struct evmc_context* context,
|
||||||
|
enum evmc_revision rev,
|
||||||
|
const struct evmc_message* msg,
|
||||||
|
uint8_t const* code,
|
||||||
|
size_t code_size)
|
||||||
|
{
|
||||||
|
return instance->execute(instance, context, rev, msg, code, code_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Releases the resources allocated to the execution result.
|
||||||
|
*
|
||||||
|
* @see evmc_release_result_fn
|
||||||
|
*/
|
||||||
|
static inline void evmc_release_result(struct evmc_result* result)
|
||||||
|
{
|
||||||
|
result->release(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helpers for optional storage of evmc_result.
|
||||||
|
*
|
||||||
|
* In some contexts (i.e. evmc_result::create_address is unused) objects of
|
||||||
|
* type evmc_result contains a memory storage that MAY be used by the object
|
||||||
|
* owner. This group defines helper types and functions for accessing
|
||||||
|
* the optional storage.
|
||||||
|
*
|
||||||
|
* @defgroup result_optional_storage Result Optional Storage
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The union representing evmc_result "optional storage".
|
||||||
|
*
|
||||||
|
* The evmc_result struct contains 24 bytes of optional storage that can be
|
||||||
|
* reused by the object creator if the object does not contain
|
||||||
|
* evmc_result::create_address.
|
||||||
|
*
|
||||||
|
* A VM implementation MAY use this memory to keep additional data
|
||||||
|
* when returning result from evmc_execute_fn().
|
||||||
|
* The host application MAY use this memory to keep additional data
|
||||||
|
* when returning result of performed calls from evmc_call_fn().
|
||||||
|
*
|
||||||
|
* @see evmc_get_optional_storage(), evmc_get_const_optional_storage().
|
||||||
|
*/
|
||||||
|
union evmc_result_optional_storage
|
||||||
|
{
|
||||||
|
uint8_t bytes[24]; /**< 24 bytes of optional storage. */
|
||||||
|
void* pointer; /**< Optional pointer. */
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Provides read-write access to evmc_result "optional storage". */
|
||||||
|
static inline union evmc_result_optional_storage* evmc_get_optional_storage(
|
||||||
|
struct evmc_result* result)
|
||||||
|
{
|
||||||
|
return (union evmc_result_optional_storage*)&result->create_address;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Provides read-only access to evmc_result "optional storage". */
|
||||||
|
static inline const union evmc_result_optional_storage* evmc_get_const_optional_storage(
|
||||||
|
const struct evmc_result* result)
|
||||||
|
{
|
||||||
|
return (const union evmc_result_optional_storage*)&result->create_address;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/** @} */
|
||||||
28
vendor/github.com/ethereum/evmc/bindings/go/evmc/host.c
generated
vendored
Normal file
28
vendor/github.com/ethereum/evmc/bindings/go/evmc/host.c
generated
vendored
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
/* EVMC: Ethereum Client-VM Connector API.
|
||||||
|
* Copyright 2018 The EVMC Authors.
|
||||||
|
* Licensed under the Apache License, Version 2.0. See the LICENSE file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "_cgo_export.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
const struct evmc_context_fn_table evmc_go_fn_table = {
|
||||||
|
(evmc_account_exists_fn)accountExists,
|
||||||
|
(evmc_get_storage_fn)getStorage,
|
||||||
|
(evmc_set_storage_fn)setStorage,
|
||||||
|
(evmc_get_balance_fn)getBalance,
|
||||||
|
(evmc_get_code_size_fn)getCodeSize,
|
||||||
|
(evmc_get_code_hash_fn)getCodeHash,
|
||||||
|
(evmc_copy_code_fn)copyCode,
|
||||||
|
(evmc_selfdestruct_fn)selfdestruct,
|
||||||
|
(evmc_call_fn)call,
|
||||||
|
(evmc_get_tx_context_fn)getTxContext,
|
||||||
|
(evmc_get_block_hash_fn)getBlockHash,
|
||||||
|
(evmc_emit_log_fn)emitLog,
|
||||||
|
};
|
||||||
|
|
||||||
|
void evmc_go_free_result_output(const struct evmc_result* result)
|
||||||
|
{
|
||||||
|
free((void*)result->output_data);
|
||||||
|
}
|
||||||
238
vendor/github.com/ethereum/evmc/bindings/go/evmc/host.go
generated
vendored
Normal file
238
vendor/github.com/ethereum/evmc/bindings/go/evmc/host.go
generated
vendored
Normal file
|
|
@ -0,0 +1,238 @@
|
||||||
|
// EVMC: Ethereum Client-VM Connector API.
|
||||||
|
// Copyright 2018 The EVMC Authors.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See the LICENSE file.
|
||||||
|
|
||||||
|
package evmc
|
||||||
|
|
||||||
|
/*
|
||||||
|
#cgo CFLAGS: -I${SRCDIR}/.. -Wall -Wextra -Wno-unused-parameter
|
||||||
|
|
||||||
|
#include <evmc/evmc.h>
|
||||||
|
|
||||||
|
struct extended_context
|
||||||
|
{
|
||||||
|
struct evmc_context context;
|
||||||
|
int64_t index;
|
||||||
|
};
|
||||||
|
|
||||||
|
void evmc_go_free_result_output(const struct evmc_result* result);
|
||||||
|
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
import (
|
||||||
|
"math/big"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CallKind int
|
||||||
|
|
||||||
|
const (
|
||||||
|
Call CallKind = C.EVMC_CALL
|
||||||
|
DelegateCall CallKind = C.EVMC_DELEGATECALL
|
||||||
|
CallCode CallKind = C.EVMC_CALLCODE
|
||||||
|
Create CallKind = C.EVMC_CREATE
|
||||||
|
Create2 CallKind = C.EVMC_CREATE2
|
||||||
|
)
|
||||||
|
|
||||||
|
type StorageStatus int
|
||||||
|
|
||||||
|
const (
|
||||||
|
StorageUnchanged StorageStatus = C.EVMC_STORAGE_UNCHANGED
|
||||||
|
StorageModified StorageStatus = C.EVMC_STORAGE_MODIFIED
|
||||||
|
StorageAdded StorageStatus = C.EVMC_STORAGE_ADDED
|
||||||
|
StorageDeleted StorageStatus = C.EVMC_STORAGE_DELETED
|
||||||
|
)
|
||||||
|
|
||||||
|
func goAddress(in C.struct_evmc_address) common.Address {
|
||||||
|
out := common.Address{}
|
||||||
|
for i := 0; i < len(out); i++ {
|
||||||
|
out[i] = byte(in.bytes[i])
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
func goHash(in C.struct_evmc_uint256be) common.Hash {
|
||||||
|
out := common.Hash{}
|
||||||
|
for i := 0; i < len(out); i++ {
|
||||||
|
out[i] = byte(in.bytes[i])
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
func goByteSlice(data *C.uint8_t, size C.size_t) []byte {
|
||||||
|
if size == 0 {
|
||||||
|
return []byte{}
|
||||||
|
}
|
||||||
|
return (*[1 << 30]byte)(unsafe.Pointer(data))[:size:size]
|
||||||
|
}
|
||||||
|
|
||||||
|
type HostContext interface {
|
||||||
|
AccountExists(addr common.Address) bool
|
||||||
|
GetStorage(addr common.Address, key common.Hash) common.Hash
|
||||||
|
SetStorage(addr common.Address, key common.Hash, value common.Hash) StorageStatus
|
||||||
|
GetBalance(addr common.Address) common.Hash
|
||||||
|
GetCodeSize(addr common.Address) int
|
||||||
|
GetCodeHash(addr common.Address) common.Hash
|
||||||
|
GetCode(addr common.Address) []byte
|
||||||
|
Selfdestruct(addr common.Address, beneficiary common.Address)
|
||||||
|
GetTxContext() (gasPrice common.Hash, origin common.Address, coinbase common.Address, number int64, timestamp int64,
|
||||||
|
gasLimit int64, difficulty common.Hash)
|
||||||
|
GetBlockHash(number int64) common.Hash
|
||||||
|
EmitLog(addr common.Address, topics []common.Hash, data []byte)
|
||||||
|
Call(kind CallKind,
|
||||||
|
destination common.Address, sender common.Address, value *big.Int, input []byte, gas int64, depth int,
|
||||||
|
static bool) (output []byte, gasLeft int64, createAddr common.Address, err error)
|
||||||
|
}
|
||||||
|
|
||||||
|
//export accountExists
|
||||||
|
func accountExists(pCtx unsafe.Pointer, pAddr *C.struct_evmc_address) C.int {
|
||||||
|
idx := int((*C.struct_extended_context)(pCtx).index)
|
||||||
|
ctx := getHostContext(idx)
|
||||||
|
exists := ctx.AccountExists(goAddress(*pAddr))
|
||||||
|
r := C.int(0)
|
||||||
|
if exists {
|
||||||
|
r = 1
|
||||||
|
}
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
//export getStorage
|
||||||
|
func getStorage(pResult *C.struct_evmc_uint256be, pCtx unsafe.Pointer, pAddr *C.struct_evmc_address, pKey *C.struct_evmc_uint256be) {
|
||||||
|
idx := int((*C.struct_extended_context)(pCtx).index)
|
||||||
|
ctx := getHostContext(idx)
|
||||||
|
value := ctx.GetStorage(goAddress(*pAddr), goHash(*pKey))
|
||||||
|
*pResult = evmcUint256be(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
//export setStorage
|
||||||
|
func setStorage(pCtx unsafe.Pointer, pAddr *C.struct_evmc_address, pKey *C.struct_evmc_uint256be, pVal *C.struct_evmc_uint256be) C.enum_evmc_storage_status {
|
||||||
|
idx := int((*C.struct_extended_context)(pCtx).index)
|
||||||
|
ctx := getHostContext(idx)
|
||||||
|
return C.enum_evmc_storage_status(ctx.SetStorage(goAddress(*pAddr), goHash(*pKey), goHash(*pVal)))
|
||||||
|
}
|
||||||
|
|
||||||
|
//export getBalance
|
||||||
|
func getBalance(pResult *C.struct_evmc_uint256be, pCtx unsafe.Pointer, pAddr *C.struct_evmc_address) {
|
||||||
|
idx := int((*C.struct_extended_context)(pCtx).index)
|
||||||
|
ctx := getHostContext(idx)
|
||||||
|
balance := ctx.GetBalance(goAddress(*pAddr))
|
||||||
|
*pResult = evmcUint256be(balance)
|
||||||
|
}
|
||||||
|
|
||||||
|
//export getCodeSize
|
||||||
|
func getCodeSize(pCtx unsafe.Pointer, pAddr *C.struct_evmc_address) C.size_t {
|
||||||
|
idx := int((*C.struct_extended_context)(pCtx).index)
|
||||||
|
ctx := getHostContext(idx)
|
||||||
|
return C.size_t(ctx.GetCodeSize(goAddress(*pAddr)))
|
||||||
|
}
|
||||||
|
|
||||||
|
//export getCodeHash
|
||||||
|
func getCodeHash(pResult *C.struct_evmc_uint256be, pCtx unsafe.Pointer, pAddr *C.struct_evmc_address) {
|
||||||
|
idx := int((*C.struct_extended_context)(pCtx).index)
|
||||||
|
ctx := getHostContext(idx)
|
||||||
|
*pResult = evmcUint256be(ctx.GetCodeHash(goAddress(*pAddr)))
|
||||||
|
}
|
||||||
|
|
||||||
|
//export copyCode
|
||||||
|
func copyCode(pCtx unsafe.Pointer, pAddr *C.struct_evmc_address, offset C.size_t, p *C.uint8_t, size C.size_t) C.size_t {
|
||||||
|
idx := int((*C.struct_extended_context)(pCtx).index)
|
||||||
|
ctx := getHostContext(idx)
|
||||||
|
code := ctx.GetCode(goAddress(*pAddr))
|
||||||
|
length := C.size_t(len(code))
|
||||||
|
|
||||||
|
if offset >= length {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
toCopy := length - offset
|
||||||
|
if toCopy > size {
|
||||||
|
toCopy = size
|
||||||
|
}
|
||||||
|
|
||||||
|
out := goByteSlice(p, size)
|
||||||
|
copy(out, code[offset:])
|
||||||
|
return toCopy
|
||||||
|
}
|
||||||
|
|
||||||
|
//export selfdestruct
|
||||||
|
func selfdestruct(pCtx unsafe.Pointer, pAddr *C.struct_evmc_address, pBeneficiary *C.struct_evmc_address) {
|
||||||
|
idx := int((*C.struct_extended_context)(pCtx).index)
|
||||||
|
ctx := getHostContext(idx)
|
||||||
|
ctx.Selfdestruct(goAddress(*pAddr), goAddress(*pBeneficiary))
|
||||||
|
}
|
||||||
|
|
||||||
|
//export getTxContext
|
||||||
|
func getTxContext(pResult unsafe.Pointer, pCtx unsafe.Pointer) {
|
||||||
|
idx := int((*C.struct_extended_context)(pCtx).index)
|
||||||
|
ctx := getHostContext(idx)
|
||||||
|
|
||||||
|
gasPrice, origin, coinbase, number, timestamp, gasLimit, difficulty := ctx.GetTxContext()
|
||||||
|
|
||||||
|
*(*C.struct_evmc_tx_context)(pResult) = C.struct_evmc_tx_context{
|
||||||
|
evmcUint256be(gasPrice),
|
||||||
|
evmcAddress(origin),
|
||||||
|
evmcAddress(coinbase),
|
||||||
|
C.int64_t(number),
|
||||||
|
C.int64_t(timestamp),
|
||||||
|
C.int64_t(gasLimit),
|
||||||
|
evmcUint256be(difficulty),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//export getBlockHash
|
||||||
|
func getBlockHash(pResult *C.struct_evmc_uint256be, pCtx unsafe.Pointer, number int64) {
|
||||||
|
idx := int((*C.struct_extended_context)(pCtx).index)
|
||||||
|
ctx := getHostContext(idx)
|
||||||
|
|
||||||
|
*pResult = evmcUint256be(ctx.GetBlockHash(number))
|
||||||
|
}
|
||||||
|
|
||||||
|
//export emitLog
|
||||||
|
func emitLog(pCtx unsafe.Pointer, pAddr *C.struct_evmc_address, pData unsafe.Pointer, dataSize C.size_t, pTopics unsafe.Pointer, topicsCount C.size_t) {
|
||||||
|
idx := int((*C.struct_extended_context)(pCtx).index)
|
||||||
|
ctx := getHostContext(idx)
|
||||||
|
|
||||||
|
// FIXME: Optimize memory copy
|
||||||
|
data := C.GoBytes(pData, C.int(dataSize))
|
||||||
|
tData := C.GoBytes(pTopics, C.int(topicsCount*32))
|
||||||
|
|
||||||
|
nTopics := int(topicsCount)
|
||||||
|
topics := make([]common.Hash, nTopics)
|
||||||
|
for i := 0; i < nTopics; i++ {
|
||||||
|
copy(topics[i][:], tData[i*32:(i+1)*32])
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.EmitLog(goAddress(*pAddr), topics, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
//export call
|
||||||
|
func call(pResult *C.struct_evmc_result, pCtx unsafe.Pointer, msg *C.struct_evmc_message) {
|
||||||
|
idx := int((*C.struct_extended_context)(pCtx).index)
|
||||||
|
ctx := getHostContext(idx)
|
||||||
|
|
||||||
|
kind := CallKind(msg.kind)
|
||||||
|
output, gasLeft, createAddr, err := ctx.Call(kind, goAddress(msg.destination), goAddress(msg.sender), goHash(msg.value).Big(),
|
||||||
|
goByteSlice(msg.input_data, msg.input_size), int64(msg.gas), int(msg.depth), msg.flags != 0)
|
||||||
|
|
||||||
|
statusCode := C.enum_evmc_status_code(0)
|
||||||
|
if err != nil {
|
||||||
|
statusCode = C.enum_evmc_status_code(err.(Error))
|
||||||
|
}
|
||||||
|
|
||||||
|
result := C.struct_evmc_result{}
|
||||||
|
result.status_code = statusCode
|
||||||
|
result.gas_left = C.int64_t(gasLeft)
|
||||||
|
result.create_address = evmcAddress(createAddr)
|
||||||
|
|
||||||
|
if len(output) > 0 {
|
||||||
|
// TODO: We could pass it directly to the caller without a copy. The caller should release it. Check depth.
|
||||||
|
cOutput := C.CBytes(output)
|
||||||
|
result.output_data = (*C.uint8_t)(cOutput)
|
||||||
|
result.output_size = C.size_t(len(output))
|
||||||
|
result.release = (C.evmc_release_result_fn)(C.evmc_go_free_result_output)
|
||||||
|
}
|
||||||
|
|
||||||
|
*pResult = result
|
||||||
|
}
|
||||||
153
vendor/github.com/ethereum/evmc/bindings/go/evmc/loader.c
generated
vendored
Normal file
153
vendor/github.com/ethereum/evmc/bindings/go/evmc/loader.c
generated
vendored
Normal file
|
|
@ -0,0 +1,153 @@
|
||||||
|
/* EVMC: Ethereum Client-VM Connector API.
|
||||||
|
* Copyright 2018 The EVMC Authors.
|
||||||
|
* Licensed under the Apache License, Version 2.0. See the LICENSE file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <evmc/loader.h>
|
||||||
|
|
||||||
|
#include <evmc/evmc.h>
|
||||||
|
#include <evmc/helpers.h>
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#if _WIN32
|
||||||
|
#include <Windows.h>
|
||||||
|
#define DLL_HANDLE HMODULE
|
||||||
|
#define DLL_OPEN(filename) LoadLibrary(filename)
|
||||||
|
#define DLL_CLOSE(handle) FreeLibrary(handle)
|
||||||
|
#define DLL_GET_CREATE_FN(handle, name) (evmc_create_fn) GetProcAddress(handle, name)
|
||||||
|
#define HAVE_STRCPY_S 1
|
||||||
|
#else
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#define DLL_HANDLE void*
|
||||||
|
#define DLL_OPEN(filename) dlopen(filename, RTLD_LAZY)
|
||||||
|
#define DLL_CLOSE(handle) dlclose(handle)
|
||||||
|
#define DLL_GET_CREATE_FN(handle, name) (evmc_create_fn)(uintptr_t) dlsym(handle, name)
|
||||||
|
#define HAVE_STRCPY_S 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define PATH_MAX_LENGTH 4096
|
||||||
|
|
||||||
|
#if !HAVE_STRCPY_S
|
||||||
|
static void strcpy_s(char* dest, size_t destsz, const char* src)
|
||||||
|
{
|
||||||
|
size_t len = strlen(src);
|
||||||
|
if (len > destsz - 1)
|
||||||
|
len = destsz - 1;
|
||||||
|
memcpy(dest, src, len);
|
||||||
|
dest[len] = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
evmc_create_fn evmc_load(const char* filename, enum evmc_loader_error_code* error_code)
|
||||||
|
{
|
||||||
|
enum evmc_loader_error_code ec = EVMC_LOADER_SUCCESS;
|
||||||
|
evmc_create_fn create_fn = NULL;
|
||||||
|
|
||||||
|
if (!filename)
|
||||||
|
{
|
||||||
|
ec = EVMC_LOADER_INVALID_ARGUMENT;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t length = strlen(filename);
|
||||||
|
if (length == 0 || length > PATH_MAX_LENGTH)
|
||||||
|
{
|
||||||
|
ec = EVMC_LOADER_INVALID_ARGUMENT;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
DLL_HANDLE handle = DLL_OPEN(filename);
|
||||||
|
if (!handle)
|
||||||
|
{
|
||||||
|
ec = EVMC_LOADER_CANNOT_OPEN;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create name buffer with the prefix.
|
||||||
|
const char prefix[] = "evmc_create_";
|
||||||
|
const size_t prefix_length = strlen(prefix);
|
||||||
|
char name[sizeof(prefix) + PATH_MAX_LENGTH];
|
||||||
|
strcpy_s(name, sizeof(name), prefix);
|
||||||
|
|
||||||
|
// Find filename in the path.
|
||||||
|
const char* sep_pos = strrchr(filename, '/');
|
||||||
|
#if _WIN32
|
||||||
|
// On Windows check also Windows classic path separator.
|
||||||
|
const char* sep_pos_windows = strrchr(filename, '\\');
|
||||||
|
sep_pos = sep_pos_windows > sep_pos ? sep_pos_windows : sep_pos;
|
||||||
|
#endif
|
||||||
|
const char* name_pos = sep_pos ? sep_pos + 1 : filename;
|
||||||
|
|
||||||
|
// Skip "lib" prefix if present.
|
||||||
|
const char lib_prefix[] = "lib";
|
||||||
|
const size_t lib_prefix_length = strlen(lib_prefix);
|
||||||
|
if (strncmp(name_pos, lib_prefix, lib_prefix_length) == 0)
|
||||||
|
name_pos += lib_prefix_length;
|
||||||
|
|
||||||
|
strcpy_s(name + prefix_length, PATH_MAX_LENGTH, name_pos);
|
||||||
|
|
||||||
|
// Trim the file extension.
|
||||||
|
char* ext_pos = strrchr(name, '.');
|
||||||
|
if (ext_pos)
|
||||||
|
*ext_pos = 0;
|
||||||
|
|
||||||
|
// Replace all "-" with "_".
|
||||||
|
char* dash_pos = name;
|
||||||
|
while ((dash_pos = strchr(dash_pos, '-')) != NULL)
|
||||||
|
*dash_pos++ = '_';
|
||||||
|
|
||||||
|
// Search for the "full name" based function name.
|
||||||
|
create_fn = DLL_GET_CREATE_FN(handle, name);
|
||||||
|
if (!create_fn)
|
||||||
|
{
|
||||||
|
// Try the "short name" based function name.
|
||||||
|
const char* short_name_pos = strrchr(name, '_');
|
||||||
|
if (short_name_pos)
|
||||||
|
{
|
||||||
|
short_name_pos += 1;
|
||||||
|
memmove(name + prefix_length, short_name_pos, strlen(short_name_pos) + 1);
|
||||||
|
create_fn = DLL_GET_CREATE_FN(handle, name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!create_fn)
|
||||||
|
create_fn = DLL_GET_CREATE_FN(handle, "evmc_create");
|
||||||
|
|
||||||
|
if (!create_fn)
|
||||||
|
{
|
||||||
|
DLL_CLOSE(handle);
|
||||||
|
ec = EVMC_LOADER_SYMBOL_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
|
if (error_code)
|
||||||
|
*error_code = ec;
|
||||||
|
return create_fn;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct evmc_instance* evmc_load_and_create(const char* filename,
|
||||||
|
enum evmc_loader_error_code* error_code)
|
||||||
|
{
|
||||||
|
evmc_create_fn create_fn = evmc_load(filename, error_code);
|
||||||
|
|
||||||
|
if (!create_fn)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
struct evmc_instance* instance = create_fn();
|
||||||
|
if (!instance)
|
||||||
|
{
|
||||||
|
*error_code = EVMC_LOADER_INSTANCE_CREATION_FAILURE;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!evmc_is_abi_compatible(instance))
|
||||||
|
{
|
||||||
|
*error_code = EVMC_LOADER_ABI_VERSION_MISMATCH;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
109
vendor/github.com/ethereum/evmc/bindings/go/evmc/loader.h
generated
vendored
Normal file
109
vendor/github.com/ethereum/evmc/bindings/go/evmc/loader.h
generated
vendored
Normal file
|
|
@ -0,0 +1,109 @@
|
||||||
|
/* EVMC: Ethereum Client-VM Connector API.
|
||||||
|
* Copyright 2018 The EVMC Authors.
|
||||||
|
* Licensed under the Apache License, Version 2.0. See the LICENSE file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EVMC Loader Library
|
||||||
|
*
|
||||||
|
* The EVMC Loader Library supports loading VMs implemented as Dynamically Loaded Libraries
|
||||||
|
* (DLLs, shared objects).
|
||||||
|
*
|
||||||
|
* @defgroup loader EVMC Loader
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** The function pointer type for EVMC create functions. */
|
||||||
|
typedef struct evmc_instance* (*evmc_create_fn)(void);
|
||||||
|
|
||||||
|
/** Error codes for the EVMC loader. */
|
||||||
|
enum evmc_loader_error_code
|
||||||
|
{
|
||||||
|
/** The loader succeeded. */
|
||||||
|
EVMC_LOADER_SUCCESS = 0,
|
||||||
|
|
||||||
|
/** The loader cannot open the given file name. */
|
||||||
|
EVMC_LOADER_CANNOT_OPEN = 1,
|
||||||
|
|
||||||
|
/** The VM create function not found. */
|
||||||
|
EVMC_LOADER_SYMBOL_NOT_FOUND = 2,
|
||||||
|
|
||||||
|
/** The invalid argument value provided. */
|
||||||
|
EVMC_LOADER_INVALID_ARGUMENT = 3,
|
||||||
|
|
||||||
|
/** The creation of a VM instance has failed. */
|
||||||
|
EVMC_LOADER_INSTANCE_CREATION_FAILURE = 4,
|
||||||
|
|
||||||
|
/** The ABI version of the VM instance has mismatched. */
|
||||||
|
EVMC_LOADER_ABI_VERSION_MISMATCH = 5,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dynamically loads the shared object (DLL) with an EVM implementation.
|
||||||
|
*
|
||||||
|
* This function tries to open a DLL at the given `filename`. On UNIX-like systems dlopen() function
|
||||||
|
* is used. On Windows LoadLibrary() function is used.
|
||||||
|
*
|
||||||
|
* If the file does not exist or is not a valid shared library the ::EVMC_LOADER_CANNOT_OPEN error
|
||||||
|
* code is signaled and NULL is returned.
|
||||||
|
*
|
||||||
|
* After the DLL is successfully loaded the function tries to find the EVM create function in the
|
||||||
|
* library. The `filename` is used to guess the EVM name and the name of the create function.
|
||||||
|
* The create function name is constructed by the following rules. Consider example path:
|
||||||
|
* "/ethereum/libexample-interpreter.so".
|
||||||
|
* - the filename is taken from the path:
|
||||||
|
* "libexample-interpreter.so",
|
||||||
|
* - the "lib" prefix and file extension are stripped from the name:
|
||||||
|
* "example-interpreter"
|
||||||
|
* - all "-" are replaced with "_" to construct _full name_:
|
||||||
|
* "example_interpreter",
|
||||||
|
* - the _full name_ is split by "_" char and the last item is taken to form the _short name_:
|
||||||
|
* "interpreter",
|
||||||
|
* - the name "evmc_create_" + _full name_ is checked in the library:
|
||||||
|
* "evmc_create_example_interpreter",
|
||||||
|
* - then, the name "evmc_create_" + _short name_ is checked in the library:
|
||||||
|
* "evmc_create_interpreter".
|
||||||
|
* - lastly, the name "evmc_create" is checked in the library
|
||||||
|
*
|
||||||
|
* If the create function is found in the library, the pointer to the function is returned.
|
||||||
|
* Otherwise, the ::EVMC_LOADER_SYMBOL_NOT_FOUND error code is signaled and NULL is returned.
|
||||||
|
*
|
||||||
|
* It is safe to call this function with the same filename argument multiple times
|
||||||
|
* (the DLL is not going to be loaded multiple times).
|
||||||
|
*
|
||||||
|
* @param filename The null terminated path (absolute or relative) to the shared library
|
||||||
|
* containing the EVM implementation. If the value is NULL, an empty C-string
|
||||||
|
* or longer than the path maximum length the ::EVMC_LOADER_INVALID_ARGUMENT is
|
||||||
|
* signaled.
|
||||||
|
* @param error_code The pointer to the error code. If not NULL the value is set to
|
||||||
|
* ::EVMC_LOADER_SUCCESS on success or any other error code as described above.
|
||||||
|
* @return The pointer to the EVM create function or NULL.
|
||||||
|
*/
|
||||||
|
evmc_create_fn evmc_load(const char* filename, enum evmc_loader_error_code* error_code);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dynamically loads the VM DLL and creates the VM instance.
|
||||||
|
*
|
||||||
|
* This is a macro for creating the VM instance with the function returned from evmc_load().
|
||||||
|
* The function signals the same errors as evmc_load() and additionally:
|
||||||
|
* - ::EVMC_LOADER_INSTANCE_CREATION_FAILURE when the create function returns NULL,
|
||||||
|
* - ::EVMC_LOADER_ABI_VERSION_MISMATCH when the created VM instance has ABI version different
|
||||||
|
* from the ABI version of this library (::EVMC_ABI_VERSION).
|
||||||
|
*
|
||||||
|
* It is safe to call this function with the same filename argument multiple times:
|
||||||
|
* the DLL is not going to be loaded multiple times, but the function will return new VM instance
|
||||||
|
* each time.
|
||||||
|
*/
|
||||||
|
struct evmc_instance* evmc_load_and_create(const char* filename,
|
||||||
|
enum evmc_loader_error_code* error_code);
|
||||||
|
|
||||||
|
#if __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** @} */
|
||||||
8
vendor/vendor.json
vendored
8
vendor/vendor.json
vendored
|
|
@ -104,6 +104,14 @@
|
||||||
"revision": "a3814ce5008e612a0c6d027608b54e1d0d9a5613",
|
"revision": "a3814ce5008e612a0c6d027608b54e1d0d9a5613",
|
||||||
"revisionTime": "2018-01-22T22:25:45Z"
|
"revisionTime": "2018-01-22T22:25:45Z"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"checksumSHA1": "gvcZHEaRD0J5Y6QrFTo0GrR2TkE=",
|
||||||
|
"path": "github.com/ethereum/evmc/bindings/go/evmc",
|
||||||
|
"revision": "224080ef8c8d99f5cfe59067a3bd995be23349bf",
|
||||||
|
"revisionTime": "2018-08-28T21:11:56Z",
|
||||||
|
"version": "=v5.2.0",
|
||||||
|
"versionExact": "v5.2.0"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "7oFpbmDfGobwKsFLIf6wMUvVoKw=",
|
"checksumSHA1": "7oFpbmDfGobwKsFLIf6wMUvVoKw=",
|
||||||
"path": "github.com/fatih/color",
|
"path": "github.com/fatih/color",
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue