{"action":"created","comment":{"url":"https://api.github.com/repos/paritytech/wasmi/pulls/comments/196829903","pull_request_review_id":130447084,"id":196829903,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDE5NjgyOTkwMw==","diff_hunk":"@@ -99,397 +223,1071 @@ impl Validator {\n \t\t}\n \t}\n \n-\tfn validate_instruction(context: &mut FunctionValidationContext, opcode: &Opcode) -> Result<InstructionOutcome, Error> {\n+\tfn read_instruction(context: &mut FunctionValidationContext, opcode: &Opcode) -> Result<Outcome, Error> {\n \t\tuse self::Opcode::*;\n \t\tmatch *opcode {\n-\t\t\tUnreachable => Ok(InstructionOutcome::Unreachable),\n-\t\t\tNop => Ok(InstructionOutcome::ValidateNextInstruction),\n-\t\t\tBlock(block_type) => Validator::validate_block(context, block_type),\n-\t\t\tLoop(block_type) => Validator::validate_loop(context, block_type),\n-\t\t\tIf(block_type) => Validator::validate_if(context, block_type),\n-\t\t\tElse => Validator::validate_else(context),\n-\t\t\tEnd => Validator::validate_end(context),\n-\t\t\tBr(idx) => Validator::validate_br(context, idx),\n-\t\t\tBrIf(idx) => Validator::validate_br_if(context, idx),\n-\t\t\tBrTable(ref table, default) => Validator::validate_br_table(context, table, default),\n-\t\t\tReturn => Validator::validate_return(context),\n-\n-\t\t\tCall(index) => Validator::validate_call(context, index),\n-\t\t\tCallIndirect(index, _reserved) => Validator::validate_call_indirect(context, index),\n-\n-\t\t\tDrop => Validator::validate_drop(context),\n-\t\t\tSelect => Validator::validate_select(context),\n-\n-\t\t\tGetLocal(index) => Validator::validate_get_local(context, index),\n-\t\t\tSetLocal(index) => Validator::validate_set_local(context, index),\n-\t\t\tTeeLocal(index) => Validator::validate_tee_local(context, index),\n-\t\t\tGetGlobal(index) => Validator::validate_get_global(context, index),\n-\t\t\tSetGlobal(index) => Validator::validate_set_global(context, index),\n-\n-\t\t\tI32Load(align, _) => Validator::validate_load(context, align, 4, ValueType::I32),\n-\t\t\tI64Load(align, _) => Validator::validate_load(context, align, 8, ValueType::I64),\n-\t\t\tF32Load(align, _) => Validator::validate_load(context, align, 4, ValueType::F32),\n-\t\t\tF64Load(align, _) => Validator::validate_load(context, align, 8, ValueType::F64),\n-\t\t\tI32Load8S(align, _) => Validator::validate_load(context, align, 1, ValueType::I32),\n-\t\t\tI32Load8U(align, _) => Validator::validate_load(context, align, 1, ValueType::I32),\n-\t\t\tI32Load16S(align, _) => Validator::validate_load(context, align, 2, ValueType::I32),\n-\t\t\tI32Load16U(align, _) => Validator::validate_load(context, align, 2, ValueType::I32),\n-\t\t\tI64Load8S(align, _) => Validator::validate_load(context, align, 1, ValueType::I64),\n-\t\t\tI64Load8U(align, _) => Validator::validate_load(context, align, 1, ValueType::I64),\n-\t\t\tI64Load16S(align, _) => Validator::validate_load(context, align, 2, ValueType::I64),\n-\t\t\tI64Load16U(align, _) => Validator::validate_load(context, align, 2, ValueType::I64),\n-\t\t\tI64Load32S(align, _) => Validator::validate_load(context, align, 4, ValueType::I64),\n-\t\t\tI64Load32U(align, _) => Validator::validate_load(context, align, 4, ValueType::I64),\n-\n-\t\t\tI32Store(align, _) => Validator::validate_store(context, align, 4, ValueType::I32),\n-\t\t\tI64Store(align, _) => Validator::validate_store(context, align, 8, ValueType::I64),\n-\t\t\tF32Store(align, _) => Validator::validate_store(context, align, 4, ValueType::F32),\n-\t\t\tF64Store(align, _) => Validator::validate_store(context, align, 8, ValueType::F64),\n-\t\t\tI32Store8(align, _) => Validator::validate_store(context, align, 1, ValueType::I32),\n-\t\t\tI32Store16(align, _) => Validator::validate_store(context, align, 2, ValueType::I32),\n-\t\t\tI64Store8(align, _) => Validator::validate_store(context, align, 1, ValueType::I64),\n-\t\t\tI64Store16(align, _) => Validator::validate_store(context, align, 2, ValueType::I64),\n-\t\t\tI64Store32(align, _) => Validator::validate_store(context, align, 4, ValueType::I64),\n-\n-\t\t\tCurrentMemory(_) => Validator::validate_current_memory(context),\n-\t\t\tGrowMemory(_) => Validator::validate_grow_memory(context),\n-\n-\t\t\tI32Const(_) => Validator::validate_const(context, ValueType::I32),\n-\t\t\tI64Const(_) => Validator::validate_const(context, ValueType::I64),\n-\t\t\tF32Const(_) => Validator::validate_const(context, ValueType::F32),\n-\t\t\tF64Const(_) => Validator::validate_const(context, ValueType::F64),\n-\n-\t\t\tI32Eqz => Validator::validate_testop(context, ValueType::I32),\n-\t\t\tI32Eq => Validator::validate_relop(context, ValueType::I32),\n-\t\t\tI32Ne => Validator::validate_relop(context, ValueType::I32),\n-\t\t\tI32LtS => Validator::validate_relop(context, ValueType::I32),\n-\t\t\tI32LtU => Validator::validate_relop(context, ValueType::I32),\n-\t\t\tI32GtS => Validator::validate_relop(context, ValueType::I32),\n-\t\t\tI32GtU => Validator::validate_relop(context, ValueType::I32),\n-\t\t\tI32LeS => Validator::validate_relop(context, ValueType::I32),\n-\t\t\tI32LeU => Validator::validate_relop(context, ValueType::I32),\n-\t\t\tI32GeS => Validator::validate_relop(context, ValueType::I32),\n-\t\t\tI32GeU => Validator::validate_relop(context, ValueType::I32),\n-\n-\t\t\tI64Eqz => Validator::validate_testop(context, ValueType::I64),\n-\t\t\tI64Eq => Validator::validate_relop(context, ValueType::I64),\n-\t\t\tI64Ne => Validator::validate_relop(context, ValueType::I64),\n-\t\t\tI64LtS => Validator::validate_relop(context, ValueType::I64),\n-\t\t\tI64LtU => Validator::validate_relop(context, ValueType::I64),\n-\t\t\tI64GtS => Validator::validate_relop(context, ValueType::I64),\n-\t\t\tI64GtU => Validator::validate_relop(context, ValueType::I64),\n-\t\t\tI64LeS => Validator::validate_relop(context, ValueType::I64),\n-\t\t\tI64LeU => Validator::validate_relop(context, ValueType::I64),\n-\t\t\tI64GeS => Validator::validate_relop(context, ValueType::I64),\n-\t\t\tI64GeU => Validator::validate_relop(context, ValueType::I64),\n-\n-\t\t\tF32Eq => Validator::validate_relop(context, ValueType::F32),\n-\t\t\tF32Ne => Validator::validate_relop(context, ValueType::F32),\n-\t\t\tF32Lt => Validator::validate_relop(context, ValueType::F32),\n-\t\t\tF32Gt => Validator::validate_relop(context, ValueType::F32),\n-\t\t\tF32Le => Validator::validate_relop(context, ValueType::F32),\n-\t\t\tF32Ge => Validator::validate_relop(context, ValueType::F32),\n-\n-\t\t\tF64Eq => Validator::validate_relop(context, ValueType::F64),\n-\t\t\tF64Ne => Validator::validate_relop(context, ValueType::F64),\n-\t\t\tF64Lt => Validator::validate_relop(context, ValueType::F64),\n-\t\t\tF64Gt => Validator::validate_relop(context, ValueType::F64),\n-\t\t\tF64Le => Validator::validate_relop(context, ValueType::F64),\n-\t\t\tF64Ge => Validator::validate_relop(context, ValueType::F64),\n-\n-\t\t\tI32Clz => Validator::validate_unop(context, ValueType::I32),\n-\t\t\tI32Ctz => Validator::validate_unop(context, ValueType::I32),\n-\t\t\tI32Popcnt => Validator::validate_unop(context, ValueType::I32),\n-\t\t\tI32Add => Validator::validate_binop(context, ValueType::I32),\n-\t\t\tI32Sub => Validator::validate_binop(context, ValueType::I32),\n-\t\t\tI32Mul => Validator::validate_binop(context, ValueType::I32),\n-\t\t\tI32DivS => Validator::validate_binop(context, ValueType::I32),\n-\t\t\tI32DivU => Validator::validate_binop(context, ValueType::I32),\n-\t\t\tI32RemS => Validator::validate_binop(context, ValueType::I32),\n-\t\t\tI32RemU => Validator::validate_binop(context, ValueType::I32),\n-\t\t\tI32And => Validator::validate_binop(context, ValueType::I32),\n-\t\t\tI32Or => Validator::validate_binop(context, ValueType::I32),\n-\t\t\tI32Xor => Validator::validate_binop(context, ValueType::I32),\n-\t\t\tI32Shl => Validator::validate_binop(context, ValueType::I32),\n-\t\t\tI32ShrS => Validator::validate_binop(context, ValueType::I32),\n-\t\t\tI32ShrU => Validator::validate_binop(context, ValueType::I32),\n-\t\t\tI32Rotl => Validator::validate_binop(context, ValueType::I32),\n-\t\t\tI32Rotr => Validator::validate_binop(context, ValueType::I32),\n-\n-\t\t\tI64Clz => Validator::validate_unop(context, ValueType::I64),\n-\t\t\tI64Ctz => Validator::validate_unop(context, ValueType::I64),\n-\t\t\tI64Popcnt => Validator::validate_unop(context, ValueType::I64),\n-\t\t\tI64Add => Validator::validate_binop(context, ValueType::I64),\n-\t\t\tI64Sub => Validator::validate_binop(context, ValueType::I64),\n-\t\t\tI64Mul => Validator::validate_binop(context, ValueType::I64),\n-\t\t\tI64DivS => Validator::validate_binop(context, ValueType::I64),\n-\t\t\tI64DivU => Validator::validate_binop(context, ValueType::I64),\n-\t\t\tI64RemS => Validator::validate_binop(context, ValueType::I64),\n-\t\t\tI64RemU => Validator::validate_binop(context, ValueType::I64),\n-\t\t\tI64And => Validator::validate_binop(context, ValueType::I64),\n-\t\t\tI64Or => Validator::validate_binop(context, ValueType::I64),\n-\t\t\tI64Xor => Validator::validate_binop(context, ValueType::I64),\n-\t\t\tI64Shl => Validator::validate_binop(context, ValueType::I64),\n-\t\t\tI64ShrS => Validator::validate_binop(context, ValueType::I64),\n-\t\t\tI64ShrU => Validator::validate_binop(context, ValueType::I64),\n-\t\t\tI64Rotl => Validator::validate_binop(context, ValueType::I64),\n-\t\t\tI64Rotr => Validator::validate_binop(context, ValueType::I64),\n-\n-\t\t\tF32Abs => Validator::validate_unop(context, ValueType::F32),\n-\t\t\tF32Neg => Validator::validate_unop(context, ValueType::F32),\n-\t\t\tF32Ceil => Validator::validate_unop(context, ValueType::F32),\n-\t\t\tF32Floor => Validator::validate_unop(context, ValueType::F32),\n-\t\t\tF32Trunc => Validator::validate_unop(context, ValueType::F32),\n-\t\t\tF32Nearest => Validator::validate_unop(context, ValueType::F32),\n-\t\t\tF32Sqrt => Validator::validate_unop(context, ValueType::F32),\n-\t\t\tF32Add => Validator::validate_binop(context, ValueType::F32),\n-\t\t\tF32Sub => Validator::validate_binop(context, ValueType::F32),\n-\t\t\tF32Mul => Validator::validate_binop(context, ValueType::F32),\n-\t\t\tF32Div => Validator::validate_binop(context, ValueType::F32),\n-\t\t\tF32Min => Validator::validate_binop(context, ValueType::F32),\n-\t\t\tF32Max => Validator::validate_binop(context, ValueType::F32),\n-\t\t\tF32Copysign => Validator::validate_binop(context, ValueType::F32),\n-\n-\t\t\tF64Abs => Validator::validate_unop(context, ValueType::F64),\n-\t\t\tF64Neg => Validator::validate_unop(context, ValueType::F64),\n-\t\t\tF64Ceil => Validator::validate_unop(context, ValueType::F64),\n-\t\t\tF64Floor => Validator::validate_unop(context, ValueType::F64),\n-\t\t\tF64Trunc => Validator::validate_unop(context, ValueType::F64),\n-\t\t\tF64Nearest => Validator::validate_unop(context, ValueType::F64),\n-\t\t\tF64Sqrt => Validator::validate_unop(context, ValueType::F64),\n-\t\t\tF64Add => Validator::validate_binop(context, ValueType::F64),\n-\t\t\tF64Sub => Validator::validate_binop(context, ValueType::F64),\n-\t\t\tF64Mul => Validator::validate_binop(context, ValueType::F64),\n-\t\t\tF64Div => Validator::validate_binop(context, ValueType::F64),\n-\t\t\tF64Min => Validator::validate_binop(context, ValueType::F64),\n-\t\t\tF64Max => Validator::validate_binop(context, ValueType::F64),\n-\t\t\tF64Copysign => Validator::validate_binop(context, ValueType::F64),\n-\n-\t\t\tI32WrapI64 => Validator::validate_cvtop(context, ValueType::I64, ValueType::I32),\n-\t\t\tI32TruncSF32 => Validator::validate_cvtop(context, ValueType::F32, ValueType::I32),\n-\t\t\tI32TruncUF32 => Validator::validate_cvtop(context, ValueType::F32, ValueType::I32),\n-\t\t\tI32TruncSF64 => Validator::validate_cvtop(context, ValueType::F64, ValueType::I32),\n-\t\t\tI32TruncUF64 => Validator::validate_cvtop(context, ValueType::F64, ValueType::I32),\n-\t\t\tI64ExtendSI32 => Validator::validate_cvtop(context, ValueType::I32, ValueType::I64),\n-\t\t\tI64ExtendUI32 => Validator::validate_cvtop(context, ValueType::I32, ValueType::I64),\n-\t\t\tI64TruncSF32 => Validator::validate_cvtop(context, ValueType::F32, ValueType::I64),\n-\t\t\tI64TruncUF32 => Validator::validate_cvtop(context, ValueType::F32, ValueType::I64),\n-\t\t\tI64TruncSF64 => Validator::validate_cvtop(context, ValueType::F64, ValueType::I64),\n-\t\t\tI64TruncUF64 => Validator::validate_cvtop(context, ValueType::F64, ValueType::I64),\n-\t\t\tF32ConvertSI32 => Validator::validate_cvtop(context, ValueType::I32, ValueType::F32),\n-\t\t\tF32ConvertUI32 => Validator::validate_cvtop(context, ValueType::I32, ValueType::F32),\n-\t\t\tF32ConvertSI64 => Validator::validate_cvtop(context, ValueType::I64, ValueType::F32),\n-\t\t\tF32ConvertUI64 => Validator::validate_cvtop(context, ValueType::I64, ValueType::F32),\n-\t\t\tF32DemoteF64 => Validator::validate_cvtop(context, ValueType::F64, ValueType::F32),\n-\t\t\tF64ConvertSI32 => Validator::validate_cvtop(context, ValueType::I32, ValueType::F64),\n-\t\t\tF64ConvertUI32 => Validator::validate_cvtop(context, ValueType::I32, ValueType::F64),\n-\t\t\tF64ConvertSI64 => Validator::validate_cvtop(context, ValueType::I64, ValueType::F64),\n-\t\t\tF64ConvertUI64 => Validator::validate_cvtop(context, ValueType::I64, ValueType::F64),\n-\t\t\tF64PromoteF32 => Validator::validate_cvtop(context, ValueType::F32, ValueType::F64),\n-\n-\t\t\tI32ReinterpretF32 => Validator::validate_cvtop(context, ValueType::F32, ValueType::I32),\n-\t\t\tI64ReinterpretF64 => Validator::validate_cvtop(context, ValueType::F64, ValueType::I64),\n-\t\t\tF32ReinterpretI32 => Validator::validate_cvtop(context, ValueType::I32, ValueType::F32),\n-\t\t\tF64ReinterpretI64 => Validator::validate_cvtop(context, ValueType::I64, ValueType::F64),\n-\t\t}\n-\t}\n-\n-\tfn validate_const(context: &mut FunctionValidationContext, value_type: ValueType) -> Result<InstructionOutcome, Error> {\n-\t\tcontext.push_value(value_type.into())?;\n-\t\tOk(InstructionOutcome::ValidateNextInstruction)\n-\t}\n-\n-\tfn validate_unop(context: &mut FunctionValidationContext, value_type: ValueType) -> Result<InstructionOutcome, Error> {\n-\t\tcontext.pop_value(value_type.into())?;\n-\t\tcontext.push_value(value_type.into())?;\n-\t\tOk(InstructionOutcome::ValidateNextInstruction)\n-\t}\n-\n-\tfn validate_binop(context: &mut FunctionValidationContext, value_type: ValueType) -> Result<InstructionOutcome, Error> {\n-\t\tcontext.pop_value(value_type.into())?;\n-\t\tcontext.pop_value(value_type.into())?;\n-\t\tcontext.push_value(value_type.into())?;\n-\t\tOk(InstructionOutcome::ValidateNextInstruction)\n-\t}\n-\n-\tfn validate_testop(context: &mut FunctionValidationContext, value_type: ValueType) -> Result<InstructionOutcome, Error> {\n-\t\tcontext.pop_value(value_type.into())?;\n-\t\tcontext.push_value(ValueType::I32.into())?;\n-\t\tOk(InstructionOutcome::ValidateNextInstruction)\n-\t}\n-\n-\tfn validate_relop(context: &mut FunctionValidationContext, value_type: ValueType) -> Result<InstructionOutcome, Error> {\n-\t\tcontext.pop_value(value_type.into())?;\n-\t\tcontext.pop_value(value_type.into())?;\n-\t\tcontext.push_value(ValueType::I32.into())?;\n-\t\tOk(InstructionOutcome::ValidateNextInstruction)\n-\t}\n-\n-\tfn validate_cvtop(context: &mut FunctionValidationContext, value_type1: ValueType, value_type2: ValueType) -> Result<InstructionOutcome, Error> {\n-\t\tcontext.pop_value(value_type1.into())?;\n-\t\tcontext.push_value(value_type2.into())?;\n-\t\tOk(InstructionOutcome::ValidateNextInstruction)\n-\t}\n-\n-\tfn validate_drop(context: &mut FunctionValidationContext) -> Result<InstructionOutcome, Error> {\n-\t\tcontext.pop_value(StackValueType::Any).map(|_| ())?;\n-\t\tOk(InstructionOutcome::ValidateNextInstruction)\n-\t}\n-\n-\tfn validate_select(context: &mut FunctionValidationContext) -> Result<InstructionOutcome, Error> {\n-\t\tcontext.pop_value(ValueType::I32.into())?;\n-\t\tlet select_type = context.pop_value(StackValueType::Any)?;\n-\t\tcontext.pop_value(select_type)?;\n-\t\tcontext.push_value(select_type)?;\n-\t\tOk(InstructionOutcome::ValidateNextInstruction)\n-\t}\n-\n-\tfn validate_get_local(context: &mut FunctionValidationContext, index: u32) -> Result<InstructionOutcome, Error> {\n-\t\tlet local_type = context.require_local(index)?;\n-\t\tcontext.push_value(local_type)?;\n-\t\tOk(InstructionOutcome::ValidateNextInstruction)\n-\t}\n-\n-\tfn validate_set_local(context: &mut FunctionValidationContext, index: u32) -> Result<InstructionOutcome, Error> {\n-\t\tlet local_type = context.require_local(index)?;\n-\t\tlet value_type = context.pop_value(StackValueType::Any)?;\n-\t\tif local_type != value_type {\n+\t\t\t// Nop instruction doesn't do anything. It is safe to just skip it.\n+\t\t\tNop => {},\n+\n+\t\t\tUnreachable => {\n+\t\t\t\tcontext.sink.emit(isa::Instruction::Unreachable);\n+\t\t\t\treturn Ok(Outcome::Unreachable);\n+\t\t\t}\n+\n+\t\t\tBlock(block_type) => {\n+\t\t\t\tlet end_label = context.sink.new_label();\n+\t\t\t\tpush_label(\n+\t\t\t\t\tBlockFrameType::Block {\n+\t\t\t\t\t\tend_label\n+\t\t\t\t\t},\n+\t\t\t\t\tblock_type,\n+\t\t\t\t\tcontext.position,\n+\t\t\t\t\t&context.value_stack,\n+\t\t\t\t\t&mut context.frame_stack,\n+\t\t\t\t)?;\n+\t\t\t}\n+\t\t\tLoop(block_type) => {\n+\t\t\t\t// Resolve loop header right away.\n+\t\t\t\tlet header = context.sink.new_label();\n+\t\t\t\tcontext.sink.resolve_label(header);\n+\n+\t\t\t\tpush_label(\n+\t\t\t\t\tBlockFrameType::Loop {\n+\t\t\t\t\t\theader,\n+\t\t\t\t\t},\n+\t\t\t\t\tblock_type,\n+\t\t\t\t\tcontext.position,\n+\t\t\t\t\t&context.value_stack,\n+\t\t\t\t\t&mut context.frame_stack,\n+\t\t\t\t)?;\n+\t\t\t}\n+\t\t\tIf(block_type) => {\n+\t\t\t\t// `if_not` will be resolved whenever `End` or `Else` operator will be met.\n+\t\t\t\t// `end_label` will always be resolved at `End`.\n+\t\t\t\tlet if_not = context.sink.new_label();\n+\t\t\t\tlet end_label = context.sink.new_label();\n+\n+\t\t\t\tpop_value(&mut context.value_stack, &context.frame_stack, ValueType::I32.into())?;\n+\t\t\t\tpush_label(\n+\t\t\t\t\tBlockFrameType::IfTrue {\n+\t\t\t\t\t\tif_not,\n+\t\t\t\t\t\tend_label,\n+\t\t\t\t\t},\n+\t\t\t\t\tblock_type,\n+\t\t\t\t\tcontext.position,\n+\t\t\t\t\t&context.value_stack,\n+\t\t\t\t\t&mut context.frame_stack,\n+\t\t\t\t)?;\n+\n+\t\t\t\tcontext.sink.emit_br_eqz(Target {\n+\t\t\t\t\tlabel: if_not,\n+\t\t\t\t\tdrop_keep: isa::DropKeep { drop: 0, keep: isa::Keep::None, },\n+\t\t\t\t});\n+\t\t\t}\n+\t\t\tElse => {\n+\t\t\t\tlet (block_type, if_not, end_label) = {\n+\t\t\t\t\tlet top_frame = top_label(\n+\t\t\t\t\t\t&context.frame_stack,\n+\t\t\t\t\t);\n+\n+\t\t\t\t\tlet (if_not, end_label) = match top_frame.frame_type {\n+\t\t\t\t\t\tBlockFrameType::IfTrue { if_not, end_label } => (if_not, end_label),\n+\t\t\t\t\t\t_ => return Err(Error(\"Misplaced else instruction\".into())),\n+\t\t\t\t\t};\n+\t\t\t\t\t(top_frame.block_type, if_not, end_label)\n+\t\t\t\t};\n+\n+\t\t\t\t// First, we need to finish if-true block: add a jump from the end of the if-true block\n+\t\t\t\t// to the \"end_label\" (it will be resolved at End).\n+\t\t\t\tcontext.sink.emit_br(Target {\n+\t\t\t\t\tlabel: end_label,\n+\t\t\t\t\tdrop_keep: isa::DropKeep { drop: 0, keep: isa::Keep::None, },\n+\t\t\t\t});\n+\n+\t\t\t\t// Resolve `if_not` to here so when if condition is unsatisfied control flow\n+\t\t\t\t// will jump to this label.\n+\t\t\t\tcontext.sink.resolve_label(if_not);\n+\n+\t\t\t\t// Then, we pop the current label. It discards all values that pushed in the current\n+\t\t\t\t// frame.\n+\t\t\t\tpop_label(\n+\t\t\t\t\t&mut context.value_stack,\n+\t\t\t\t\t&mut context.frame_stack\n+\t\t\t\t)?;\n+\t\t\t\tpush_label(\n+\t\t\t\t\tBlockFrameType::IfFalse {\n+\t\t\t\t\t\tend_label,\n+\t\t\t\t\t},\n+\t\t\t\t\tblock_type,\n+\t\t\t\t\tcontext.position,\n+\t\t\t\t\t&context.value_stack,\n+\t\t\t\t\t&mut context.frame_stack,\n+\t\t\t\t)?;\n+\t\t\t}\n+\t\t\tEnd => {\n+\t\t\t\tlet (frame_type, block_type) = {\n+\t\t\t\t\tlet top = top_label(&context.frame_stack);\n+\t\t\t\t\t(top.frame_type, top.block_type)\n+\t\t\t\t};\n+\n+\t\t\t\tif let BlockFrameType::IfTrue { if_not, .. } = frame_type {\n+\t\t\t\t\t// A `if` without an `else` can't return a result.\n+\t\t\t\t\tif block_type != BlockType::NoResult {\n+\t\t\t\t\t\treturn Err(\n+\t\t\t\t\t\t\tError(\n+\t\t\t\t\t\t\t\tformat!(\n+\t\t\t\t\t\t\t\t\t\"If block without else required to have NoResult block type. But it has {:?} type\",\n+\t\t\t\t\t\t\t\t\tblock_type\n+\t\t\t\t\t\t\t\t)\n+\t\t\t\t\t\t\t)\n+\t\t\t\t\t\t);\n+\t\t\t\t\t}\n+\n+\t\t\t\t\t// Resolve `if_not` label. If the `if's` condition doesn't hold the control will jump\n+\t\t\t\t\t// to here.\n+\t\t\t\t\tcontext.sink.resolve_label(if_not);\n+\t\t\t\t}\n+\n+\t\t\t\t// Unless it's a loop, resolve the `end_label` position here.\n+\t\t\t\tif !frame_type.is_loop() {\n+\t\t\t\t\tlet end_label = frame_type.end_label();\n+\t\t\t\t\tcontext.sink.resolve_label(end_label);\n+\t\t\t\t}\n+\n+\t\t\t\tif context.frame_stack.len() == 1 {\n+\t\t\t\t\t// We are about to close the last frame. Insert\n+\t\t\t\t\t// an explicit return.\n+\n+\t\t\t\t\t// Check the return type.\n+\t\t\t\t\tif let BlockType::Value(value_type) = context.return_type()? {\n+\t\t\t\t\t\ttee_value(\n+\t\t\t\t\t\t\t&mut context.value_stack,\n+\t\t\t\t\t\t\t&context.frame_stack,\n+\t\t\t\t\t\t\tvalue_type.into()\n+\t\t\t\t\t\t)?;\n+\t\t\t\t\t}\n+\n+\t\t\t\t\t// Emit the return instruction.\n+\t\t\t\t\tlet drop_keep = drop_keep_return(\n+\t\t\t\t\t\t&context.locals,\n+\t\t\t\t\t\t&context.value_stack,\n+\t\t\t\t\t\t&context.frame_stack,\n+\t\t\t\t\t);\n+\t\t\t\t\tcontext.sink.emit(isa::Instruction::Return(drop_keep));\n+\t\t\t\t}\n+\n+\t\t\t\tpop_label(&mut context.value_stack, &mut context.frame_stack)?;\n+\n+\t\t\t\t// Push the result value.\n+\t\t\t\tif let BlockType::Value(value_type) = block_type {\n+\t\t\t\t\tpush_value(&mut context.value_stack, value_type.into())?;\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\tBr(depth) => {\n+\t\t\t\tValidator::validate_br(context, depth)?;\n+\n+\t\t\t\tlet target = require_target(\n+\t\t\t\t\tdepth,\n+\t\t\t\t\t&context.value_stack,\n+\t\t\t\t\t&context.frame_stack,\n+\t\t\t\t);\n+\t\t\t\tcontext.sink.emit_br(target);\n+\n+\t\t\t\treturn Ok(Outcome::Unreachable);\n+\t\t\t}\n+\t\t\tBrIf(depth) => {\n+\t\t\t\tValidator::validate_br_if(context, depth)?;\n+\n+\t\t\t\tlet target = require_target(\n+\t\t\t\t\tdepth,\n+\t\t\t\t\t&context.value_stack,\n+\t\t\t\t\t&context.frame_stack,\n+\t\t\t\t);\n+\t\t\t\tcontext.sink.emit_br_nez(target);\n+\t\t\t}\n+\t\t\tBrTable(ref table, default) => {\n+\t\t\t\tValidator::validate_br_table(context, table, default)?;\n+\n+\t\t\t\tlet mut targets = Vec::new();\n+\t\t\t\tfor depth in table.iter() {\n+\t\t\t\t\tlet target = require_target(\n+\t\t\t\t\t\t*depth,\n+\t\t\t\t\t\t&context.value_stack,\n+\t\t\t\t\t\t&context.frame_stack,\n+\t\t\t\t\t);\n+\t\t\t\t\ttargets.push(target);\n+\t\t\t\t}\n+\t\t\t\tlet default_target = require_target(\n+\t\t\t\t\tdefault,\n+\t\t\t\t\t&context.value_stack,\n+\t\t\t\t\t&context.frame_stack,\n+\t\t\t\t);\n+\t\t\t\tcontext.sink.emit_br_table(&targets, default_target);\n+\n+\t\t\t\treturn Ok(Outcome::Unreachable);\n+\t\t\t}\n+\t\t\tReturn => {\n+\t\t\t\tif let BlockType::Value(value_type) = context.return_type()? {\n+\t\t\t\t\ttee_value(&mut context.value_stack, &context.frame_stack, value_type.into())?;\n+\t\t\t\t}\n+\n+\t\t\t\tlet drop_keep = drop_keep_return(\n+\t\t\t\t\t&context.locals,\n+\t\t\t\t\t&context.value_stack,\n+\t\t\t\t\t&context.frame_stack\n+\t\t\t\t);\n+\t\t\t\tcontext.sink.emit(isa::Instruction::Return(drop_keep));\n+\n+\t\t\t\treturn Ok(Outcome::Unreachable);\n+\t\t\t}\n+\n+\t\t\tCall(index) => {\n+\t\t\t\tValidator::validate_call(context, index)?;\n+\t\t\t\tcontext.sink.emit(isa::Instruction::Call(index));\n+\t\t\t}\n+\t\t\tCallIndirect(index, _reserved) => {\n+\t\t\t\tValidator::validate_call_indirect(context, index)?;\n+\t\t\t\tcontext.sink.emit(isa::Instruction::CallIndirect(index));\n+\t\t\t}\n+\n+\t\t\tDrop => {\n+\t\t\t\tValidator::validate_drop(context)?;\n+\t\t\t\tcontext.sink.emit(isa::Instruction::Drop);\n+\t\t\t}\n+\t\t\tSelect => {\n+\t\t\t\tValidator::validate_select(context)?;\n+\t\t\t\tcontext.sink.emit(isa::Instruction::Select);\n+\t\t\t}\n+\n+\t\t\tGetLocal(index) => {\n+\t\t\t\t// We need to calculate relative depth before validation since\n+\t\t\t\t// it will change the value stack size.\n+\t\t\t\tlet depth = relative_local_depth(\n+\t\t\t\t\tindex,\n+\t\t\t\t\t&context.locals,\n+\t\t\t\t\t&context.value_stack,\n+\t\t\t\t)?;\n+\t\t\t\tValidator::validate_get_local(context, index)?;\n+\t\t\t\tcontext.sink.emit(\n+\t\t\t\t\tisa::Instruction::GetLocal(depth),\n+\t\t\t\t);\n+\t\t\t}\n+\t\t\tSetLocal(index) => {\n+\t\t\t\tValidator::validate_set_local(context, index)?;\n+\t\t\t\tlet depth = relative_local_depth(\n+\t\t\t\t\tindex,\n+\t\t\t\t\t&context.locals,\n+\t\t\t\t\t&context.value_stack,\n+\t\t\t\t)?;\n+\t\t\t\tcontext.sink.emit(\n+\t\t\t\t\tisa::Instruction::SetLocal(depth),\n+\t\t\t\t);\n+\t\t\t}\n+\t\t\tTeeLocal(index) => {\n+\t\t\t\tValidator::validate_tee_local(context, index)?;\n+\t\t\t\tlet depth = relative_local_depth(\n+\t\t\t\t\tindex,\n+\t\t\t\t\t&context.locals,\n+\t\t\t\t\t&context.value_stack,\n+\t\t\t\t)?;\n+\t\t\t\tcontext.sink.emit(\n+\t\t\t\t\tisa::Instruction::TeeLocal(depth),\n+\t\t\t\t);\n+\t\t\t}\n+\t\t\tGetGlobal(index) => {\n+\t\t\t\tValidator::validate_get_global(context, index)?;\n+\t\t\t\tcontext.sink.emit(isa::Instruction::GetGlobal(index));\n+\t\t\t}\n+\t\t\tSetGlobal(index) => {\n+\t\t\t\tValidator::validate_set_global(context, index)?;\n+\t\t\t\tcontext.sink.emit(isa::Instruction::SetGlobal(index));\n+\t\t\t}\n+\n+\t\t\tI32Load(align, offset) => {","path":"src/validation/func.rs","position":788,"original_position":788,"commit_id":"7f864d6a7c99cf1aa6b8325616994f2ff3464688","original_commit_id":"7f864d6a7c99cf1aa6b8325616994f2ff3464688","user":{"login":"Vurich","id":29733394,"node_id":"MDQ6VXNlcjI5NzMzMzk0","avatar_url":"https://avatars0.githubusercontent.com/u/29733394?v=4","gravatar_id":"","url":"https://api.github.com/users/Vurich","html_url":"https://github.com/Vurich","followers_url":"https://api.github.com/users/Vurich/followers","following_url":"https://api.github.com/users/Vurich/following{/other_user}","gists_url":"https://api.github.com/users/Vurich/gists{/gist_id}","starred_url":"https://api.github.com/users/Vurich/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Vurich/subscriptions","organizations_url":"https://api.github.com/users/Vurich/orgs","repos_url":"https://api.github.com/users/Vurich/repos","events_url":"https://api.github.com/users/Vurich/events{/privacy}","received_events_url":"https://api.github.com/users/Vurich/received_events","type":"User","site_admin":false},"body":"Could you generate this with a macro? It seems error-prone.","created_at":"2018-06-20T15:34:34Z","updated_at":"2018-06-20T15:36:52Z","html_url":"https://github.com/paritytech/wasmi/pull/98#discussion_r196829903","pull_request_url":"https://api.github.com/repos/paritytech/wasmi/pulls/98","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/paritytech/wasmi/pulls/comments/196829903"},"html":{"href":"https://github.com/paritytech/wasmi/pull/98#discussion_r196829903"},"pull_request":{"href":"https://api.github.com/repos/paritytech/wasmi/pulls/98"}}},"pull_request":{"url":"https://api.github.com/repos/paritytech/wasmi/pulls/98","id":195591837,"node_id":"MDExOlB1bGxSZXF1ZXN0MTk1NTkxODM3","html_url":"https://github.com/paritytech/wasmi/pull/98","diff_url":"https://github.com/paritytech/wasmi/pull/98.diff","patch_url":"https://github.com/paritytech/wasmi/pull/98.patch","issue_url":"https://api.github.com/repos/paritytech/wasmi/issues/98","number":98,"state":"open","locked":false,"title":"Optimizations","user":{"login":"pepyakin","id":2205845,"node_id":"MDQ6VXNlcjIyMDU4NDU=","avatar_url":"https://avatars2.githubusercontent.com/u/2205845?v=4","gravatar_id":"","url":"https://api.github.com/users/pepyakin","html_url":"https://github.com/pepyakin","followers_url":"https://api.github.com/users/pepyakin/followers","following_url":"https://api.github.com/users/pepyakin/following{/other_user}","gists_url":"https://api.github.com/users/pepyakin/gists{/gist_id}","starred_url":"https://api.github.com/users/pepyakin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pepyakin/subscriptions","organizations_url":"https://api.github.com/users/pepyakin/orgs","repos_url":"https://api.github.com/users/pepyakin/repos","events_url":"https://api.github.com/users/pepyakin/events{/privacy}","received_events_url":"https://api.github.com/users/pepyakin/received_events","type":"User","site_admin":false},"body":"Based on #97 \r\n\r\nWasm isn't the greatest instruction set for interpretation. The reason for that is that Wasm is more optimized for ease of validation and compilation. \r\n\r\nThe central theme of this PR is a transformation of Wasm structured stack machine into a plain stack machine. This transformation is performed once before the interpretation alongside with validation.\r\n\r\nSee \"isa.rs\" for more details on this topic.\r\n\r\nBeyond this there a couple of optimizations here and there. \r\n\r\nWith all of this, the overall increase in the performance is about almost 2x on some benchmarks.","created_at":"2018-06-18T17:13:22Z","updated_at":"2018-06-20T15:36:52Z","closed_at":null,"merged_at":null,"merge_commit_sha":"3623ffe9cd1b2d47fad4544835e58f2255ccb994","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/paritytech/wasmi/pulls/98/commits","review_comments_url":"https://api.github.com/repos/paritytech/wasmi/pulls/98/comments","review_comment_url":"https://api.github.com/repos/paritytech/wasmi/pulls/comments{/number}","comments_url":"https://api.github.com/repos/paritytech/wasmi/issues/98/comments","statuses_url":"https://api.github.com/repos/paritytech/wasmi/statuses/7f864d6a7c99cf1aa6b8325616994f2ff3464688","head":{"label":"paritytech:flat-stack","ref":"flat-stack","sha":"7f864d6a7c99cf1aa6b8325616994f2ff3464688","user":{"login":"paritytech","id":14176906,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE0MTc2OTA2","avatar_url":"https://avatars2.githubusercontent.com/u/14176906?v=4","gravatar_id":"","url":"https://api.github.com/users/paritytech","html_url":"https://github.com/paritytech","followers_url":"https://api.github.com/users/paritytech/followers","following_url":"https://api.github.com/users/paritytech/following{/other_user}","gists_url":"https://api.github.com/users/paritytech/gists{/gist_id}","starred_url":"https://api.github.com/users/paritytech/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/paritytech/subscriptions","organizations_url":"https://api.github.com/users/paritytech/orgs","repos_url":"https://api.github.com/users/paritytech/repos","events_url":"https://api.github.com/users/paritytech/events{/privacy}","received_events_url":"https://api.github.com/users/paritytech/received_events","type":"Organization","site_admin":false},"repo":{"id":118469706,"node_id":"MDEwOlJlcG9zaXRvcnkxMTg0Njk3MDY=","name":"wasmi","full_name":"paritytech/wasmi","owner":{"login":"paritytech","id":14176906,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE0MTc2OTA2","avatar_url":"https://avatars2.githubusercontent.com/u/14176906?v=4","gravatar_id":"","url":"https://api.github.com/users/paritytech","html_url":"https://github.com/paritytech","followers_url":"https://api.github.com/users/paritytech/followers","following_url":"https://api.github.com/users/paritytech/following{/other_user}","gists_url":"https://api.github.com/users/paritytech/gists{/gist_id}","starred_url":"https://api.github.com/users/paritytech/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/paritytech/subscriptions","organizations_url":"https://api.github.com/users/paritytech/orgs","repos_url":"https://api.github.com/users/paritytech/repos","events_url":"https://api.github.com/users/paritytech/events{/privacy}","received_events_url":"https://api.github.com/users/paritytech/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/paritytech/wasmi","description":"Wasm interpreter in Rust","fork":false,"url":"https://api.github.com/repos/paritytech/wasmi","forks_url":"https://api.github.com/repos/paritytech/wasmi/forks","keys_url":"https://api.github.com/repos/paritytech/wasmi/keys{/key_id}","collaborators_url":"https://api.github.com/repos/paritytech/wasmi/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/paritytech/wasmi/teams","hooks_url":"https://api.github.com/repos/paritytech/wasmi/hooks","issue_events_url":"https://api.github.com/repos/paritytech/wasmi/issues/events{/number}","events_url":"https://api.github.com/repos/paritytech/wasmi/events","assignees_url":"https://api.github.com/repos/paritytech/wasmi/assignees{/user}","branches_url":"https://api.github.com/repos/paritytech/wasmi/branches{/branch}","tags_url":"https://api.github.com/repos/paritytech/wasmi/tags","blobs_url":"https://api.github.com/repos/paritytech/wasmi/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/paritytech/wasmi/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/paritytech/wasmi/git/refs{/sha}","trees_url":"https://api.github.com/repos/paritytech/wasmi/git/trees{/sha}","statuses_url":"https://api.github.com/repos/paritytech/wasmi/statuses/{sha}","languages_url":"https://api.github.com/repos/paritytech/wasmi/languages","stargazers_url":"https://api.github.com/repos/paritytech/wasmi/stargazers","contributors_url":"https://api.github.com/repos/paritytech/wasmi/contributors","subscribers_url":"https://api.github.com/repos/paritytech/wasmi/subscribers","subscription_url":"https://api.github.com/repos/paritytech/wasmi/subscription","commits_url":"https://api.github.com/repos/paritytech/wasmi/commits{/sha}","git_commits_url":"https://api.github.com/repos/paritytech/wasmi/git/commits{/sha}","comments_url":"https://api.github.com/repos/paritytech/wasmi/comments{/number}","issue_comment_url":"https://api.github.com/repos/paritytech/wasmi/issues/comments{/number}","contents_url":"https://api.github.com/repos/paritytech/wasmi/contents/{+path}","compare_url":"https://api.github.com/repos/paritytech/wasmi/compare/{base}...{head}","merges_url":"https://api.github.com/repos/paritytech/wasmi/merges","archive_url":"https://api.github.com/repos/paritytech/wasmi/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/paritytech/wasmi/downloads","issues_url":"https://api.github.com/repos/paritytech/wasmi/issues{/number}","pulls_url":"https://api.github.com/repos/paritytech/wasmi/pulls{/number}","milestones_url":"https://api.github.com/repos/paritytech/wasmi/milestones{/number}","notifications_url":"https://api.github.com/repos/paritytech/wasmi/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/paritytech/wasmi/labels{/name}","releases_url":"https://api.github.com/repos/paritytech/wasmi/releases{/id}","deployments_url":"https://api.github.com/repos/paritytech/wasmi/deployments","created_at":"2018-01-22T14:41:58Z","updated_at":"2018-06-20T11:18:27Z","pushed_at":"2018-06-20T11:04:21Z","git_url":"git://github.com/paritytech/wasmi.git","ssh_url":"git@github.com:paritytech/wasmi.git","clone_url":"https://github.com/paritytech/wasmi.git","svn_url":"https://github.com/paritytech/wasmi","homepage":"https://paritytech.github.io/wasmi/","size":7289,"stargazers_count":102,"watchers_count":102,"language":"Rust","has_issues":true,"has_projects":false,"has_downloads":true,"has_wiki":false,"has_pages":true,"forks_count":8,"mirror_url":null,"archived":false,"open_issues_count":20,"license":{"key":"other","name":"Other","spdx_id":null,"url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":8,"open_issues":20,"watchers":102,"default_branch":"master"}},"base":{"label":"paritytech:master","ref":"master","sha":"94b797de44eebf4309b5ccac7a977fa07f5c7b6c","user":{"login":"paritytech","id":14176906,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE0MTc2OTA2","avatar_url":"https://avatars2.githubusercontent.com/u/14176906?v=4","gravatar_id":"","url":"https://api.github.com/users/paritytech","html_url":"https://github.com/paritytech","followers_url":"https://api.github.com/users/paritytech/followers","following_url":"https://api.github.com/users/paritytech/following{/other_user}","gists_url":"https://api.github.com/users/paritytech/gists{/gist_id}","starred_url":"https://api.github.com/users/paritytech/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/paritytech/subscriptions","organizations_url":"https://api.github.com/users/paritytech/orgs","repos_url":"https://api.github.com/users/paritytech/repos","events_url":"https://api.github.com/users/paritytech/events{/privacy}","received_events_url":"https://api.github.com/users/paritytech/received_events","type":"Organization","site_admin":false},"repo":{"id":118469706,"node_id":"MDEwOlJlcG9zaXRvcnkxMTg0Njk3MDY=","name":"wasmi","full_name":"paritytech/wasmi","owner":{"login":"paritytech","id":14176906,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE0MTc2OTA2","avatar_url":"https://avatars2.githubusercontent.com/u/14176906?v=4","gravatar_id":"","url":"https://api.github.com/users/paritytech","html_url":"https://github.com/paritytech","followers_url":"https://api.github.com/users/paritytech/followers","following_url":"https://api.github.com/users/paritytech/following{/other_user}","gists_url":"https://api.github.com/users/paritytech/gists{/gist_id}","starred_url":"https://api.github.com/users/paritytech/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/paritytech/subscriptions","organizations_url":"https://api.github.com/users/paritytech/orgs","repos_url":"https://api.github.com/users/paritytech/repos","events_url":"https://api.github.com/users/paritytech/events{/privacy}","received_events_url":"https://api.github.com/users/paritytech/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/paritytech/wasmi","description":"Wasm interpreter in Rust","fork":false,"url":"https://api.github.com/repos/paritytech/wasmi","forks_url":"https://api.github.com/repos/paritytech/wasmi/forks","keys_url":"https://api.github.com/repos/paritytech/wasmi/keys{/key_id}","collaborators_url":"https://api.github.com/repos/paritytech/wasmi/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/paritytech/wasmi/teams","hooks_url":"https://api.github.com/repos/paritytech/wasmi/hooks","issue_events_url":"https://api.github.com/repos/paritytech/wasmi/issues/events{/number}","events_url":"https://api.github.com/repos/paritytech/wasmi/events","assignees_url":"https://api.github.com/repos/paritytech/wasmi/assignees{/user}","branches_url":"https://api.github.com/repos/paritytech/wasmi/branches{/branch}","tags_url":"https://api.github.com/repos/paritytech/wasmi/tags","blobs_url":"https://api.github.com/repos/paritytech/wasmi/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/paritytech/wasmi/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/paritytech/wasmi/git/refs{/sha}","trees_url":"https://api.github.com/repos/paritytech/wasmi/git/trees{/sha}","statuses_url":"https://api.github.com/repos/paritytech/wasmi/statuses/{sha}","languages_url":"https://api.github.com/repos/paritytech/wasmi/languages","stargazers_url":"https://api.github.com/repos/paritytech/wasmi/stargazers","contributors_url":"https://api.github.com/repos/paritytech/wasmi/contributors","subscribers_url":"https://api.github.com/repos/paritytech/wasmi/subscribers","subscription_url":"https://api.github.com/repos/paritytech/wasmi/subscription","commits_url":"https://api.github.com/repos/paritytech/wasmi/commits{/sha}","git_commits_url":"https://api.github.com/repos/paritytech/wasmi/git/commits{/sha}","comments_url":"https://api.github.com/repos/paritytech/wasmi/comments{/number}","issue_comment_url":"https://api.github.com/repos/paritytech/wasmi/issues/comments{/number}","contents_url":"https://api.github.com/repos/paritytech/wasmi/contents/{+path}","compare_url":"https://api.github.com/repos/paritytech/wasmi/compare/{base}...{head}","merges_url":"https://api.github.com/repos/paritytech/wasmi/merges","archive_url":"https://api.github.com/repos/paritytech/wasmi/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/paritytech/wasmi/downloads","issues_url":"https://api.github.com/repos/paritytech/wasmi/issues{/number}","pulls_url":"https://api.github.com/repos/paritytech/wasmi/pulls{/number}","milestones_url":"https://api.github.com/repos/paritytech/wasmi/milestones{/number}","notifications_url":"https://api.github.com/repos/paritytech/wasmi/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/paritytech/wasmi/labels{/name}","releases_url":"https://api.github.com/repos/paritytech/wasmi/releases{/id}","deployments_url":"https://api.github.com/repos/paritytech/wasmi/deployments","created_at":"2018-01-22T14:41:58Z","updated_at":"2018-06-20T11:18:27Z","pushed_at":"2018-06-20T11:04:21Z","git_url":"git://github.com/paritytech/wasmi.git","ssh_url":"git@github.com:paritytech/wasmi.git","clone_url":"https://github.com/paritytech/wasmi.git","svn_url":"https://github.com/paritytech/wasmi","homepage":"https://paritytech.github.io/wasmi/","size":7289,"stargazers_count":102,"watchers_count":102,"language":"Rust","has_issues":true,"has_projects":false,"has_downloads":true,"has_wiki":false,"has_pages":true,"forks_count":8,"mirror_url":null,"archived":false,"open_issues_count":20,"license":{"key":"other","name":"Other","spdx_id":null,"url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":8,"open_issues":20,"watchers":102,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/paritytech/wasmi/pulls/98"},"html":{"href":"https://github.com/paritytech/wasmi/pull/98"},"issue":{"href":"https://api.github.com/repos/paritytech/wasmi/issues/98"},"comments":{"href":"https://api.github.com/repos/paritytech/wasmi/issues/98/comments"},"review_comments":{"href":"https://api.github.com/repos/paritytech/wasmi/pulls/98/comments"},"review_comment":{"href":"https://api.github.com/repos/paritytech/wasmi/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/paritytech/wasmi/pulls/98/commits"},"statuses":{"href":"https://api.github.com/repos/paritytech/wasmi/statuses/7f864d6a7c99cf1aa6b8325616994f2ff3464688"}},"author_association":"COLLABORATOR"}}
{"actor":{"display_login":"Vurich"}}