mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #10454 from ethereum/ewasm-cleanup
[ewasm] Clean up some builtins and fix text representation of `select`
This commit is contained in:
commit
e10712c173
@ -107,33 +107,24 @@ bytes toBytes(Export _export)
|
||||
return toBytes(uint8_t(_export));
|
||||
}
|
||||
|
||||
// NOTE: This is a subset of WebAssembly opcodes.
|
||||
// Those available as a builtin are listed further down.
|
||||
enum class Opcode: uint8_t
|
||||
{
|
||||
Unreachable = 0x00,
|
||||
Nop = 0x01,
|
||||
Block = 0x02,
|
||||
Loop = 0x03,
|
||||
If = 0x04,
|
||||
Else = 0x05,
|
||||
Try = 0x06,
|
||||
Catch = 0x07,
|
||||
Throw = 0x08,
|
||||
Rethrow = 0x09,
|
||||
BrOnExn = 0x0a,
|
||||
End = 0x0b,
|
||||
Br = 0x0c,
|
||||
BrIf = 0x0d,
|
||||
BrTable = 0x0e,
|
||||
BrTable = 0x0e, // Not used yet.
|
||||
Return = 0x0f,
|
||||
Call = 0x10,
|
||||
CallIndirect = 0x11,
|
||||
ReturnCall = 0x12,
|
||||
ReturnCallIndirect = 0x13,
|
||||
Drop = 0x1a,
|
||||
Select = 0x1b,
|
||||
CallIndirect = 0x11, // Not used yet.
|
||||
LocalGet = 0x20,
|
||||
LocalSet = 0x21,
|
||||
LocalTee = 0x22,
|
||||
LocalTee = 0x22, // Not used yet.
|
||||
GlobalGet = 0x23,
|
||||
GlobalSet = 0x24,
|
||||
I32Const = 0x41,
|
||||
@ -156,6 +147,10 @@ Opcode constOpcodeFor(ValueType _type)
|
||||
}
|
||||
|
||||
static map<string, uint8_t> const builtins = {
|
||||
{"unreachable", 0x00},
|
||||
{"nop", 0x01},
|
||||
{"i32.drop", 0x1a},
|
||||
{"i64.drop", 0x1a},
|
||||
{"i32.select", 0x1b},
|
||||
{"i64.select", 0x1b},
|
||||
{"i32.load", 0x28},
|
||||
@ -381,30 +376,21 @@ bytes BinaryTransform::operator()(BuiltinCall const& _call)
|
||||
return toBytes(Opcode::I64Const) + lebEncodeSigned(static_cast<int64_t>(m_subModulePosAndSize.at(name).second));
|
||||
}
|
||||
|
||||
yulAssert(builtins.count(_call.functionName), "Builtin " + _call.functionName + " not found");
|
||||
// NOTE: the dialect ensures we have the right amount of arguments
|
||||
bytes args = visit(_call.arguments);
|
||||
bytes ret = move(args) + toBytes(builtins.at(_call.functionName));
|
||||
if (
|
||||
_call.functionName.find(".load") != string::npos ||
|
||||
_call.functionName.find(".store") != string::npos
|
||||
)
|
||||
// Alignment hint and offset. Interpreters ignore the alignment. JITs/AOTs can take it
|
||||
// into account to generate more efficient code but if the hint is invalid it could
|
||||
// actually be more expensive. It's best to hint at 1-byte alignment if we don't plan
|
||||
// to control the memory layout accordingly.
|
||||
ret += bytes{{0, 0}}; // 2^0 == 1-byte alignment
|
||||
|
||||
if (_call.functionName == "unreachable")
|
||||
return toBytes(Opcode::Unreachable);
|
||||
else if (_call.functionName == "nop")
|
||||
return toBytes(Opcode::Nop);
|
||||
else if (_call.functionName == "i32.drop" || _call.functionName == "i64.drop")
|
||||
return toBytes(Opcode::Drop);
|
||||
else
|
||||
{
|
||||
yulAssert(builtins.count(_call.functionName), "Builtin " + _call.functionName + " not found");
|
||||
bytes ret = move(args) + toBytes(builtins.at(_call.functionName));
|
||||
if (
|
||||
_call.functionName.find(".load") != string::npos ||
|
||||
_call.functionName.find(".store") != string::npos
|
||||
)
|
||||
// Alignment hint and offset. Interpreters ignore the alignment. JITs/AOTs can take it
|
||||
// into account to generate more efficient code but if the hint is invalid it could
|
||||
// actually be more expensive. It's best to hint at 1-byte alignment if we don't plan
|
||||
// to control the memory layout accordingly.
|
||||
ret += bytes{{0, 0}}; // 2^0 == 1-byte alignment
|
||||
|
||||
return ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bytes BinaryTransform::operator()(FunctionCall const& _call)
|
||||
|
@ -122,8 +122,11 @@ string TextTransform::operator()(wasm::BuiltinCall const& _builtinCall)
|
||||
{
|
||||
string args = joinTransformed(_builtinCall.arguments);
|
||||
string funcName = _builtinCall.functionName;
|
||||
// These are prefixed in the dialect, but are actually overloaded instructions in WebAssembly.
|
||||
if (funcName == "i32.drop" || funcName == "i64.drop")
|
||||
funcName = "drop";
|
||||
else if (funcName == "i32.select" || funcName == "i64.select")
|
||||
funcName = "select";
|
||||
return "(" + funcName + (args.empty() ? "" : " " + args) + ")";
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,7 @@ struct Object;
|
||||
*
|
||||
* Builtin functions are a subset of the wasm instructions.
|
||||
*
|
||||
* There is a builtin function `i32.drop` that takes an i32, while `drop` takes i64.
|
||||
* There is a builtin function `i32.drop` that takes an i32, while `i64.drop` takes i64.
|
||||
*
|
||||
*/
|
||||
struct WasmDialect: public Dialect
|
||||
|
@ -412,13 +412,13 @@ Text representation:
|
||||
(local.set $z (i32.const 0))
|
||||
(local.set $_1 (i32.const 4294967295))
|
||||
(block
|
||||
(local.set $condition (i32.select (local.get $_1) (i64.ne (local.get $x1) (local.get $y1)) (i64.lt_u (local.get $x1) (local.get $y1))))
|
||||
(local.set $condition (select (local.get $_1) (i64.ne (local.get $x1) (local.get $y1)) (i64.lt_u (local.get $x1) (local.get $y1))))
|
||||
(if (i32.eq (local.get $condition) (i32.const 0)) (then
|
||||
(block
|
||||
(local.set $condition_11 (i32.select (local.get $_1) (i64.ne (local.get $x2) (local.get $y2)) (i64.lt_u (local.get $x2) (local.get $y2))))
|
||||
(local.set $condition_11 (select (local.get $_1) (i64.ne (local.get $x2) (local.get $y2)) (i64.lt_u (local.get $x2) (local.get $y2))))
|
||||
(if (i32.eq (local.get $condition_11) (i32.const 0)) (then
|
||||
(block
|
||||
(local.set $condition_12 (i32.select (local.get $_1) (i64.ne (local.get $x3) (local.get $y3)) (i64.lt_u (local.get $x3) (local.get $y3))))
|
||||
(local.set $condition_12 (select (local.get $_1) (i64.ne (local.get $x3) (local.get $y3)) (i64.lt_u (local.get $x3) (local.get $y3))))
|
||||
(if (i32.eq (local.get $condition_12) (i32.const 0)) (then
|
||||
(local.set $z (i64.lt_u (local.get $x4) (local.get $y4)))
|
||||
)(else
|
||||
|
@ -19,4 +19,4 @@
|
||||
// )
|
||||
//
|
||||
// Binary:
|
||||
// 0061736d01000000010401600000020100030201000503010001060100070a01066d656d6f727902000a0801060002401a0b0b
|
||||
// 0061736d01000000010401600000020100030201000503010001060100070a01066d656d6f727902000a0d010b000240420042017c1a0b0b
|
||||
|
@ -20,4 +20,4 @@
|
||||
// )
|
||||
//
|
||||
// Binary:
|
||||
// 0061736d01000000010401600000020100030201000503010001060100071102066d656d6f72790200046d61696e00000a0801060002401a0b0b
|
||||
// 0061736d01000000010401600000020100030201000503010001060100071102066d656d6f72790200046d61696e00000a0d010b000240420042017c1a0b0b
|
||||
|
@ -11,7 +11,7 @@ object "a" {
|
||||
// (module
|
||||
// ;; custom section for sub-module
|
||||
// ;; The Keccak-256 hash of the text representation of "sub": 78ac3419d75c8d6f42f663717b8e964eeb994d77ff175145133084422dbd23d7
|
||||
// ;; (@custom "sub" "0061736d01000000010401600000020100030201000503010001060100071102066d656d6f72790200046d61696e00000a0801060002401a0b0b")
|
||||
// ;; (@custom "sub" "0061736d01000000010401600000020100030201000503010001060100071102066d656d6f72790200046d61696e00000a0a0108000240420b1a0b0b")
|
||||
// ;; custom section for data
|
||||
// ;; (@custom "str" "48656c6c6f2c20576f726c6421")
|
||||
// (memory $memory (export "memory") 1)
|
||||
@ -19,4 +19,4 @@ object "a" {
|
||||
// )
|
||||
//
|
||||
// Binary:
|
||||
// 0061736d010000000101000201000301000503010001060100070a01066d656d6f72790200003e037375620061736d01000000010401600000020100030201000503010001060100071102066d656d6f72790200046d61696e00000a0801060002401a0b0b00110373747248656c6c6f2c20576f726c64210a0100
|
||||
// 0061736d010000000101000201000301000503010001060100070a01066d656d6f727902000040037375620061736d01000000010401600000020100030201000503010001060100071102066d656d6f72790200046d61696e00000a0a0108000240420b1a0b0b00110373747248656c6c6f2c20576f726c64210a0100
|
||||
|
@ -59,8 +59,8 @@ object "A" {
|
||||
// Text:
|
||||
// (module
|
||||
// ;; custom section for sub-module
|
||||
// ;; The Keccak-256 hash of the text representation of "B": 1eeffe5bc8d8819350ead60cc71ccd92c223cf52a908330db53461eb9ac89b62
|
||||
// ;; (@custom "B" "0061736d01000000010401600000020100030201000503010001060100071102066d656d6f72790200046d61696e0000007b01430061736d01000000010401600000020100030201000503010001060100071102066d656d6f72790200046d61696e0000003c01440061736d01000000010401600000020100030201000503010001060100071102066d656d6f72790200046d61696e00000a080106000240000b0b0a0901070002401a1a0b0b003c01450061736d01000000010401600000020100030201000503010001060100071102066d656d6f72790200046d61696e00000a080106000240000b0b0a0b01090002401a1a1a1a0b0b")
|
||||
// ;; The Keccak-256 hash of the text representation of "B": ccfc48ce1c0d0542ffd25ae6858777b2f7b8a6d2b6608f679458182e719f5434
|
||||
// ;; (@custom "B" "0061736d01000000010401600000020100030201000503010001060100071102066d656d6f72790200046d61696e0000007f01430061736d01000000010401600000020100030201000503010001060100071102066d656d6f72790200046d61696e0000003c01440061736d01000000010401600000020100030201000503010001060100071102066d656d6f72790200046d61696e00000a080106000240000b0b0a0d010b00024042341a423a1a0b0b003c01450061736d01000000010401600000020100030201000503010001060100071102066d656d6f72790200046d61696e00000a080106000240000b0b0a15011300024042341a42fd001a42b5011a423a1a0b0b")
|
||||
// ;; custom section for data
|
||||
// ;; (@custom "data1" "48656c6c6f2c20576f726c6421")
|
||||
// (memory $memory (export "memory") 1)
|
||||
@ -76,4 +76,4 @@ object "A" {
|
||||
// )
|
||||
//
|
||||
// Binary:
|
||||
// 0061736d01000000010401600000020100030201000503010001060100071102066d656d6f72790200046d61696e000000fa0101420061736d01000000010401600000020100030201000503010001060100071102066d656d6f72790200046d61696e0000007b01430061736d01000000010401600000020100030201000503010001060100071102066d656d6f72790200046d61696e0000003c01440061736d01000000010401600000020100030201000503010001060100071102066d656d6f72790200046d61696e00000a080106000240000b0b0a0901070002401a1a0b0b003c01450061736d01000000010401600000020100030201000503010001060100071102066d656d6f72790200046d61696e00000a080106000240000b0b0a0b01090002401a1a1a1a0b0b001305646174613148656c6c6f2c20576f726c64210a0901070002401a1a0b0b
|
||||
// 0061736d01000000010401600000020100030201000503010001060100071102066d656d6f72790200046d61696e000000880201420061736d01000000010401600000020100030201000503010001060100071102066d656d6f72790200046d61696e0000007f01430061736d01000000010401600000020100030201000503010001060100071102066d656d6f72790200046d61696e0000003c01440061736d01000000010401600000020100030201000503010001060100071102066d656d6f72790200046d61696e00000a080106000240000b0b0a0d010b00024042341a423a1a0b0b003c01450061736d01000000010401600000020100030201000503010001060100071102066d656d6f72790200046d61696e00000a080106000240000b0b0a15011300024042341a42fd001a42b5011a423a1a0b0b001305646174613148656c6c6f2c20576f726c64210a0e010c00024042351a4286021a0b0b
|
||||
|
Loading…
Reference in New Issue
Block a user