Add global api support for llvm-lib
This commit is contained in:
		
							parent
							
								
									a7ac974f46
								
							
						
					
					
						commit
						30257e1a2b
					
				| @ -1,7 +1,7 @@ | ||||
| use reid_lib::{CmpPredicate, ConstValue, Context, FunctionFlags, Instr, TerminatorKind, Type}; | ||||
| use reid_lib::{CmpPredicate, ConstValueKind, Context, FunctionFlags, Instr, TerminatorKind, Type}; | ||||
| 
 | ||||
| fn main() { | ||||
|     use ConstValue::*; | ||||
|     use ConstValueKind::*; | ||||
|     use Instr::*; | ||||
| 
 | ||||
|     let context = Context::new("libtest"); | ||||
|  | ||||
| @ -4,8 +4,8 @@ | ||||
| use std::{cell::RefCell, rc::Rc}; | ||||
| 
 | ||||
| use crate::{ | ||||
|     Block, BlockData, CompileResult, CustomTypeKind, ErrorKind, FunctionData, Instr, InstructionData, ModuleData, | ||||
|     NamedStruct, TerminatorKind, Type, TypeCategory, TypeData, | ||||
|     Block, BlockData, CompileResult, ConstValueKind, CustomTypeKind, ErrorKind, FunctionData, Instr, InstructionData, | ||||
|     ModuleData, NamedStruct, TerminatorKind, Type, TypeCategory, TypeData, | ||||
|     debug_information::{ | ||||
|         DebugInformation, DebugLocationValue, DebugMetadataValue, DebugScopeValue, InstructionDebugRecordData, | ||||
|     }, | ||||
| @ -27,6 +27,12 @@ pub struct BlockValue(pub(crate) FunctionValue, pub(crate) usize); | ||||
| #[derive(Clone, Hash, Copy, PartialEq, Eq)] | ||||
| pub struct InstructionValue(pub(crate) BlockValue, pub(crate) usize); | ||||
| 
 | ||||
| #[derive(Clone, Hash, Copy, PartialEq, Eq)] | ||||
| pub struct ConstantValue(pub(crate) usize); | ||||
| 
 | ||||
| #[derive(Clone, Hash, Copy, PartialEq, Eq)] | ||||
| pub struct GlobalValue(pub(crate) usize); | ||||
| 
 | ||||
| #[derive(Clone)] | ||||
| pub struct ModuleHolder { | ||||
|     pub(crate) value: ModuleValue, | ||||
| @ -34,6 +40,20 @@ pub struct ModuleHolder { | ||||
|     pub(crate) functions: Vec<FunctionHolder>, | ||||
|     pub(crate) types: Vec<TypeHolder>, | ||||
|     pub(crate) debug_information: Option<DebugInformation>, | ||||
|     pub(crate) constants: Vec<ConstantValueHolder>, | ||||
|     pub(crate) globals: Vec<GlobalValueHolder>, | ||||
| } | ||||
| 
 | ||||
| #[derive(Clone)] | ||||
| pub struct ConstantValueHolder { | ||||
|     pub(crate) value: ConstantValue, | ||||
|     pub(crate) kind: ConstValueKind, | ||||
| } | ||||
| #[derive(Clone)] | ||||
| pub struct GlobalValueHolder { | ||||
|     pub(crate) value: GlobalValue, | ||||
|     pub(crate) name: String, | ||||
|     pub(crate) initializer: ConstantValue, | ||||
| } | ||||
| 
 | ||||
| #[derive(Clone)] | ||||
| @ -88,6 +108,8 @@ impl Builder { | ||||
|             functions: Vec::new(), | ||||
|             types: Vec::new(), | ||||
|             debug_information: None, | ||||
|             constants: Vec::new(), | ||||
|             globals: Vec::new(), | ||||
|         }); | ||||
|         value | ||||
|     } | ||||
| @ -168,6 +190,35 @@ impl Builder { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub(crate) unsafe fn build_constant(&self, module: ModuleValue, kind: ConstValueKind) -> ConstantValue { | ||||
|         unsafe { | ||||
|             let mut modules = self.modules.borrow_mut(); | ||||
|             let module = modules.get_unchecked_mut(module.0); | ||||
|             let value = ConstantValue(module.constants.len()); | ||||
|             module.constants.push(ConstantValueHolder { value, kind }); | ||||
|             value | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub(crate) unsafe fn add_global( | ||||
|         &self, | ||||
|         module: ModuleValue, | ||||
|         name: String, | ||||
|         initializer: ConstantValue, | ||||
|     ) -> GlobalValue { | ||||
|         unsafe { | ||||
|             let mut modules = self.modules.borrow_mut(); | ||||
|             let module = modules.get_unchecked_mut(module.0); | ||||
|             let value = GlobalValue(module.globals.len()); | ||||
|             module.globals.push(GlobalValueHolder { | ||||
|                 value, | ||||
|                 name, | ||||
|                 initializer, | ||||
|             }); | ||||
|             value | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub(crate) unsafe fn find_function(&self, module: ModuleValue, name: &String) -> Option<FunctionValue> { | ||||
|         unsafe { | ||||
|             let mut modules = self.modules.borrow_mut(); | ||||
|  | ||||
| @ -33,7 +33,7 @@ use crate::{ | ||||
| }; | ||||
| 
 | ||||
| use super::{ | ||||
|     CmpPredicate, ConstValue, Context, TerminatorKind, Type, | ||||
|     CmpPredicate, ConstValueKind, Context, TerminatorKind, Type, | ||||
|     builder::{ | ||||
|         BlockHolder, BlockValue, Builder, FunctionHolder, FunctionValue, InstructionHolder, InstructionValue, | ||||
|         ModuleHolder, | ||||
| @ -1144,32 +1144,32 @@ impl CmpPredicate { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl ConstValue { | ||||
| impl ConstValueKind { | ||||
|     fn as_llvm(&self, module: &LLVMModule) -> LLVMValueRef { | ||||
|         unsafe { | ||||
|             let t = self.get_type().as_llvm(module.context_ref, &module.types); | ||||
|             match self { | ||||
|                 ConstValue::Bool(val) => LLVMConstInt(t, *val as u64, 1), | ||||
|                 ConstValue::I8(val) => LLVMConstInt(t, *val as u64, 1), | ||||
|                 ConstValue::I16(val) => LLVMConstInt(t, *val as u64, 1), | ||||
|                 ConstValue::I32(val) => LLVMConstInt(t, *val as u64, 1), | ||||
|                 ConstValue::I64(val) => LLVMConstInt(t, *val as u64, 1), | ||||
|                 ConstValue::I128(val) => LLVMConstInt(t, *val as u64, 1), | ||||
|                 ConstValue::U8(val) => LLVMConstInt(t, *val as u64, 1), | ||||
|                 ConstValue::U16(val) => LLVMConstInt(t, *val as u64, 1), | ||||
|                 ConstValue::U32(val) => LLVMConstInt(t, *val as u64, 1), | ||||
|                 ConstValue::U64(val) => LLVMConstInt(t, *val as u64, 1), | ||||
|                 ConstValue::U128(val) => LLVMConstInt(t, *val as u64, 1), | ||||
|                 ConstValue::Str(val) => { | ||||
|                 ConstValueKind::Bool(val) => LLVMConstInt(t, *val as u64, 1), | ||||
|                 ConstValueKind::I8(val) => LLVMConstInt(t, *val as u64, 1), | ||||
|                 ConstValueKind::I16(val) => LLVMConstInt(t, *val as u64, 1), | ||||
|                 ConstValueKind::I32(val) => LLVMConstInt(t, *val as u64, 1), | ||||
|                 ConstValueKind::I64(val) => LLVMConstInt(t, *val as u64, 1), | ||||
|                 ConstValueKind::I128(val) => LLVMConstInt(t, *val as u64, 1), | ||||
|                 ConstValueKind::U8(val) => LLVMConstInt(t, *val as u64, 1), | ||||
|                 ConstValueKind::U16(val) => LLVMConstInt(t, *val as u64, 1), | ||||
|                 ConstValueKind::U32(val) => LLVMConstInt(t, *val as u64, 1), | ||||
|                 ConstValueKind::U64(val) => LLVMConstInt(t, *val as u64, 1), | ||||
|                 ConstValueKind::U128(val) => LLVMConstInt(t, *val as u64, 1), | ||||
|                 ConstValueKind::Str(val) => { | ||||
|                     LLVMBuildGlobalString(module.builder_ref, into_cstring(val).as_ptr(), c"string".as_ptr()) | ||||
|                 } | ||||
|                 ConstValue::F16(val) => LLVMConstReal(t, *val as f64), | ||||
|                 ConstValue::F32B(val) => LLVMConstReal(t, *val as f64), | ||||
|                 ConstValue::F32(val) => LLVMConstReal(t, *val as f64), | ||||
|                 ConstValue::F64(val) => LLVMConstReal(t, *val as f64), | ||||
|                 ConstValue::F80(val) => LLVMConstReal(t, *val as f64), | ||||
|                 ConstValue::F128(val) => LLVMConstReal(t, *val as f64), | ||||
|                 ConstValue::F128PPC(val) => LLVMConstReal(t, *val as f64), | ||||
|                 ConstValueKind::F16(val) => LLVMConstReal(t, *val as f64), | ||||
|                 ConstValueKind::F32B(val) => LLVMConstReal(t, *val as f64), | ||||
|                 ConstValueKind::F32(val) => LLVMConstReal(t, *val as f64), | ||||
|                 ConstValueKind::F64(val) => LLVMConstReal(t, *val as f64), | ||||
|                 ConstValueKind::F80(val) => LLVMConstReal(t, *val as f64), | ||||
|                 ConstValueKind::F128(val) => LLVMConstReal(t, *val as f64), | ||||
|                 ConstValueKind::F128PPC(val) => LLVMConstReal(t, *val as f64), | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -8,7 +8,10 @@ use builder::{BlockValue, Builder, FunctionValue, InstructionValue, ModuleValue, | ||||
| use debug_information::{DebugFileData, DebugInformation, DebugLocationValue, DebugMetadataValue}; | ||||
| use fmt::PrintableModule; | ||||
| 
 | ||||
| use crate::debug_information::DebugScopeValue; | ||||
| use crate::{ | ||||
|     builder::{ConstantValue, GlobalValue}, | ||||
|     debug_information::DebugScopeValue, | ||||
| }; | ||||
| 
 | ||||
| pub mod builder; | ||||
| pub mod compile; | ||||
| @ -121,6 +124,14 @@ impl<'ctx> Module<'ctx> { | ||||
|     pub fn get_debug_info(&self) -> &Option<DebugInformation> { | ||||
|         &self.debug_info | ||||
|     } | ||||
| 
 | ||||
|     pub fn add_constant(&self, constant: ConstValueKind) -> ConstantValue { | ||||
|         unsafe { self.builder.build_constant(self.value, constant) } | ||||
|     } | ||||
| 
 | ||||
|     pub fn add_global(&self, name: String, constant: ConstantValue) -> GlobalValue { | ||||
|         unsafe { self.builder.add_global(self.value, name, constant) } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<'ctx> Drop for Module<'ctx> { | ||||
| @ -361,7 +372,7 @@ pub enum CmpPredicate { | ||||
| #[derive(Clone)] | ||||
| pub enum Instr { | ||||
|     Param(usize), | ||||
|     Constant(ConstValue), | ||||
|     Constant(ConstValueKind), | ||||
| 
 | ||||
|     /// Add two integers
 | ||||
|     Add(InstructionValue, InstructionValue), | ||||
| @ -487,7 +498,7 @@ pub enum Type { | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Clone)] | ||||
| pub enum ConstValue { | ||||
| pub enum ConstValueKind { | ||||
|     I8(i8), | ||||
|     I16(i16), | ||||
|     I32(i32), | ||||
| @ -531,29 +542,29 @@ pub enum CustomTypeKind { | ||||
| #[derive(Debug, PartialEq, Eq, Clone, Hash)] | ||||
| pub struct NamedStruct(pub String, pub Vec<Type>); | ||||
| 
 | ||||
| impl ConstValue { | ||||
| impl ConstValueKind { | ||||
|     pub fn get_type(&self) -> Type { | ||||
|         use Type::*; | ||||
|         match self { | ||||
|             ConstValue::I8(_) => I8, | ||||
|             ConstValue::I16(_) => I16, | ||||
|             ConstValue::I32(_) => I32, | ||||
|             ConstValue::I64(_) => I64, | ||||
|             ConstValue::I128(_) => I128, | ||||
|             ConstValue::U8(_) => U8, | ||||
|             ConstValue::U16(_) => U16, | ||||
|             ConstValue::U32(_) => U32, | ||||
|             ConstValue::U64(_) => U64, | ||||
|             ConstValue::U128(_) => U128, | ||||
|             ConstValue::Str(_) => Type::Ptr(Box::new(U8)), | ||||
|             ConstValue::Bool(_) => Bool, | ||||
|             ConstValue::F16(_) => F16, | ||||
|             ConstValue::F32B(_) => F32B, | ||||
|             ConstValue::F32(_) => F32, | ||||
|             ConstValue::F64(_) => F64, | ||||
|             ConstValue::F80(_) => F80, | ||||
|             ConstValue::F128(_) => F128, | ||||
|             ConstValue::F128PPC(_) => F128PPC, | ||||
|             ConstValueKind::I8(_) => I8, | ||||
|             ConstValueKind::I16(_) => I16, | ||||
|             ConstValueKind::I32(_) => I32, | ||||
|             ConstValueKind::I64(_) => I64, | ||||
|             ConstValueKind::I128(_) => I128, | ||||
|             ConstValueKind::U8(_) => U8, | ||||
|             ConstValueKind::U16(_) => U16, | ||||
|             ConstValueKind::U32(_) => U32, | ||||
|             ConstValueKind::U64(_) => U64, | ||||
|             ConstValueKind::U128(_) => U128, | ||||
|             ConstValueKind::Str(_) => Type::Ptr(Box::new(U8)), | ||||
|             ConstValueKind::Bool(_) => Bool, | ||||
|             ConstValueKind::F16(_) => F16, | ||||
|             ConstValueKind::F32B(_) => F32B, | ||||
|             ConstValueKind::F32(_) => F32, | ||||
|             ConstValueKind::F64(_) => F64, | ||||
|             ConstValueKind::F80(_) => F80, | ||||
|             ConstValueKind::F128(_) => F128, | ||||
|             ConstValueKind::F128PPC(_) => F128PPC, | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -1,4 +1,4 @@ | ||||
| use reid_lib::{builder::InstructionValue, CmpPredicate, ConstValue, Instr, Type}; | ||||
| use reid_lib::{builder::InstructionValue, CmpPredicate, ConstValueKind, Instr, Type}; | ||||
| 
 | ||||
| use crate::{ | ||||
|     codegen::{ErrorKind, StackValueKind}, | ||||
| @ -364,7 +364,7 @@ impl IntrinsicFunction for IntrinsicSizeOf { | ||||
|     fn codegen<'ctx, 'a>(&self, scope: &mut Scope<'ctx, 'a>, _: &[StackValue]) -> Result<StackValue, ErrorKind> { | ||||
|         let instr = scope | ||||
|             .block | ||||
|             .build(Instr::Constant(reid_lib::ConstValue::U64(self.0.size_of() / 8))) | ||||
|             .build(Instr::Constant(reid_lib::ConstValueKind::U64(self.0.size_of() / 8))) | ||||
|             .unwrap(); | ||||
|         Ok(StackValue(StackValueKind::Literal(instr), self.0.clone())) | ||||
|     } | ||||
| @ -382,7 +382,7 @@ impl IntrinsicFunction for IntrinsicMalloc { | ||||
| 
 | ||||
|         let sizeof = scope | ||||
|             .block | ||||
|             .build(Instr::Constant(ConstValue::U64(self.0.size_of() / 8))) | ||||
|             .build(Instr::Constant(ConstValueKind::U64(self.0.size_of() / 8))) | ||||
|             .unwrap(); | ||||
|         let bytes = scope.block.build(Instr::Mul(sizeof, amount.instr())).unwrap(); | ||||
|         let instr = scope.block.build(Instr::FunctionCall(function, vec![bytes])).unwrap(); | ||||
| @ -394,7 +394,7 @@ impl IntrinsicFunction for IntrinsicMalloc { | ||||
| pub struct IntrinsicNullPtr(TypeKind); | ||||
| impl IntrinsicFunction for IntrinsicNullPtr { | ||||
|     fn codegen<'ctx, 'a>(&self, scope: &mut Scope<'ctx, 'a>, _: &[StackValue]) -> Result<StackValue, ErrorKind> { | ||||
|         let zero = scope.block.build(Instr::Constant(ConstValue::I8(0))).unwrap(); | ||||
|         let zero = scope.block.build(Instr::Constant(ConstValueKind::I8(0))).unwrap(); | ||||
|         let instr = scope | ||||
|             .block | ||||
|             .build(Instr::IntToPtr( | ||||
|  | ||||
| @ -9,7 +9,7 @@ use reid_lib::{ | ||||
|         DebugSubprogramData, DebugSubprogramOptionals, DebugSubprogramType, DebugTypeData, DwarfFlags, | ||||
|         InstructionDebugRecordData, | ||||
|     }, | ||||
|     CmpPredicate, ConstValue, Context, CustomTypeKind, Function, FunctionFlags, Instr, Module, NamedStruct, | ||||
|     CmpPredicate, ConstValueKind, Context, CustomTypeKind, Function, FunctionFlags, Instr, Module, NamedStruct, | ||||
|     TerminatorKind as Term, Type, | ||||
| }; | ||||
| use scope::*; | ||||
| @ -784,7 +784,7 @@ impl mir::Statement { | ||||
|                 let condition_res = condition.codegen(&mut condition_scope, state)?.unwrap(); | ||||
|                 let true_instr = condition_scope | ||||
|                     .block | ||||
|                     .build(Instr::Constant(ConstValue::Bool(true))) | ||||
|                     .build(Instr::Constant(ConstValueKind::Bool(true))) | ||||
|                     .unwrap(); | ||||
|                 let check = condition_scope | ||||
|                     .block | ||||
| @ -1031,7 +1031,7 @@ impl mir::Expression { | ||||
| 
 | ||||
|                     let first = scope | ||||
|                         .block | ||||
|                         .build_named("array.zero", Instr::Constant(ConstValue::U32(0))) | ||||
|                         .build_named("array.zero", Instr::Constant(ConstValueKind::U32(0))) | ||||
|                         .unwrap(); | ||||
|                     ( | ||||
|                         scope | ||||
| @ -1098,11 +1098,11 @@ impl mir::Expression { | ||||
| 
 | ||||
|                     let index_expr = scope | ||||
|                         .block | ||||
|                         .build_named(index.to_string(), Instr::Constant(ConstValue::U32(index as u32))) | ||||
|                         .build_named(index.to_string(), Instr::Constant(ConstValueKind::U32(index as u32))) | ||||
|                         .unwrap(); | ||||
|                     let first = scope | ||||
|                         .block | ||||
|                         .build_named("zero", Instr::Constant(ConstValue::U32(0))) | ||||
|                         .build_named("zero", Instr::Constant(ConstValueKind::U32(0))) | ||||
|                         .unwrap(); | ||||
|                     let ptr = scope | ||||
|                         .block | ||||
|  | ||||
| @ -6,7 +6,7 @@ use reid_lib::{ | ||||
|         DebugArrayType, DebugBasicType, DebugFieldType, DebugInformation, DebugLocation, DebugPointerType, | ||||
|         DebugPosition, DebugScopeValue, DebugStructType, DebugTypeData, DebugTypeValue, DwarfEncoding, DwarfFlags, | ||||
|     }, | ||||
|     Block, CmpPredicate, ConstValue, Instr, Type, | ||||
|     Block, CmpPredicate, ConstValueKind, Instr, Type, | ||||
| }; | ||||
| 
 | ||||
| use crate::{ | ||||
| @ -39,28 +39,28 @@ impl mir::Literal { | ||||
| 
 | ||||
|     pub(super) fn as_const_kind(&self) -> Instr { | ||||
|         Instr::Constant(match self.clone() { | ||||
|             mir::Literal::I8(val) => ConstValue::I8(val), | ||||
|             mir::Literal::I16(val) => ConstValue::I16(val), | ||||
|             mir::Literal::I32(val) => ConstValue::I32(val), | ||||
|             mir::Literal::I64(val) => ConstValue::I64(val), | ||||
|             mir::Literal::I128(val) => ConstValue::I128(val), | ||||
|             mir::Literal::U8(val) => ConstValue::U8(val), | ||||
|             mir::Literal::U16(val) => ConstValue::U16(val), | ||||
|             mir::Literal::U32(val) => ConstValue::U32(val), | ||||
|             mir::Literal::U64(val) => ConstValue::U64(val), | ||||
|             mir::Literal::U128(val) => ConstValue::U128(val), | ||||
|             mir::Literal::Bool(val) => ConstValue::Bool(val), | ||||
|             mir::Literal::String(val) => ConstValue::Str(val.clone()), | ||||
|             mir::Literal::Vague(VagueLiteral::Number(val)) => ConstValue::I32(val as i32), | ||||
|             mir::Literal::Vague(VagueLiteral::Decimal(val)) => ConstValue::F32(val as f32), | ||||
|             mir::Literal::F16(val) => ConstValue::F16(val), | ||||
|             mir::Literal::F32B(val) => ConstValue::F32B(val), | ||||
|             mir::Literal::F32(val) => ConstValue::F32(val), | ||||
|             mir::Literal::F64(val) => ConstValue::F64(val), | ||||
|             mir::Literal::F80(val) => ConstValue::F80(val), | ||||
|             mir::Literal::F128(val) => ConstValue::F128(val), | ||||
|             mir::Literal::F128PPC(val) => ConstValue::F128PPC(val), | ||||
|             mir::Literal::Char(c) => ConstValue::U8(c as u8), | ||||
|             mir::Literal::I8(val) => ConstValueKind::I8(val), | ||||
|             mir::Literal::I16(val) => ConstValueKind::I16(val), | ||||
|             mir::Literal::I32(val) => ConstValueKind::I32(val), | ||||
|             mir::Literal::I64(val) => ConstValueKind::I64(val), | ||||
|             mir::Literal::I128(val) => ConstValueKind::I128(val), | ||||
|             mir::Literal::U8(val) => ConstValueKind::U8(val), | ||||
|             mir::Literal::U16(val) => ConstValueKind::U16(val), | ||||
|             mir::Literal::U32(val) => ConstValueKind::U32(val), | ||||
|             mir::Literal::U64(val) => ConstValueKind::U64(val), | ||||
|             mir::Literal::U128(val) => ConstValueKind::U128(val), | ||||
|             mir::Literal::Bool(val) => ConstValueKind::Bool(val), | ||||
|             mir::Literal::String(val) => ConstValueKind::Str(val.clone()), | ||||
|             mir::Literal::Vague(VagueLiteral::Number(val)) => ConstValueKind::I32(val as i32), | ||||
|             mir::Literal::Vague(VagueLiteral::Decimal(val)) => ConstValueKind::F32(val as f32), | ||||
|             mir::Literal::F16(val) => ConstValueKind::F16(val), | ||||
|             mir::Literal::F32B(val) => ConstValueKind::F32B(val), | ||||
|             mir::Literal::F32(val) => ConstValueKind::F32(val), | ||||
|             mir::Literal::F64(val) => ConstValueKind::F64(val), | ||||
|             mir::Literal::F80(val) => ConstValueKind::F80(val), | ||||
|             mir::Literal::F128(val) => ConstValueKind::F128(val), | ||||
|             mir::Literal::F128PPC(val) => ConstValueKind::F128PPC(val), | ||||
|             mir::Literal::Char(c) => ConstValueKind::U8(c as u8), | ||||
|         }) | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -82,7 +82,6 @@ impl mir::Statement { | ||||
| 
 | ||||
| impl mir::Expression { | ||||
|     fn gen_macros(&mut self, data: &MacroPass, state: &mut MacroPassState) -> PassResult { | ||||
|         dbg!("asd?"); | ||||
|         match &mut self.0 { | ||||
|             mir::ExprKind::FunctionCall(function_call) => { | ||||
|                 if function_call.is_macro { | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user