X-Git-Url: http://nitlanguage.org diff --git a/src/icode/icode_builder.nit b/src/icode/icode_builder.nit index aee4d01..c50ab6a 100644 --- a/src/icode/icode_builder.nit +++ b/src/icode/icode_builder.nit @@ -48,8 +48,8 @@ class ICodeBuilder # Check that the reciever e is not null (IIs + IAbort) fun add_null_reciever_check(e: IRegister) do - var nul = new_register(module.type_none) - var c = expr(new IIs(e, nul), module.type_bool) + var nul = lit_null_reg + var c = expr(new IIs(e, nul), mmmodule.type_bool) var iif = new IIf(c) stmt(iif) var old_seq = seq @@ -61,7 +61,7 @@ class ICodeBuilder # Add a type cast (ITypeCheck + IAbort) in the current icode sequence fun add_type_cast(e: IRegister, stype: MMType) do - var c = expr(new ITypeCheck(e, stype), module.type_bool) + var c = expr(new ITypeCheck(iroutine.params.first, e, stype), mmmodule.type_bool) var iif = new IIf(c) stmt(iif) var old_seq = seq @@ -74,7 +74,7 @@ class ICodeBuilder fun add_attr_check(prop: MMAttribute, e: IRegister) do if not prop.signature.return_type.is_nullable then - var cond = expr(new IAttrIsset(prop, e), module.type_bool) + var cond = expr(new IAttrIsset(prop, e), mmmodule.type_bool) var iif = new IIf(cond) stmt(iif) var seq_old = seq @@ -94,7 +94,7 @@ class ICodeBuilder # Add a localized IAbort fun add_abort(s: String...) do - stmt(new IAbort(s, method, module)) + stmt(new IAbort(s, mmmodule)) end # Add an assigment to the iroutine return value @@ -114,7 +114,7 @@ class ICodeBuilder if prop.name == ne then var eqp = prop.signature.recv.local_class.select_method(ee) var eqcall = add_call(eqp, args, closcns).as(not null) - return expr(new INot(eqcall), module.type_bool) + return expr(new INot(eqcall), mmmodule.type_bool) end # TODO: Inline x==y as "x is y or (x != null and (== is not the Object one) and x.==(y))" @@ -123,9 +123,9 @@ class ICodeBuilder icall.closure_defs = closcns if prop.name == ee then # Prepare the result - var reg = new_register(module.type_bool) + var reg = new_register(mmmodule.type_bool) # "x is y" - var cond = expr(new IIs(args[0], args[1]), module.type_bool) + var cond = expr(new IIs(args[0], args[1]), mmmodule.type_bool) var iif = new IIf(cond) stmt(iif) var seq_old = seq @@ -135,16 +135,16 @@ class ICodeBuilder seq = iif.else_seq # Do the "x != null" part iff x is nullable if args[0].stype.is_nullable then - var nul = new_register(module.type_none) - cond = expr(new IIs(args[0], nul), module.type_bool) + var nul = lit_null_reg + cond = expr(new IIs(args[0], nul), mmmodule.type_bool) iif = new IIf(cond) stmt(iif) seq = iif.then_seq - add_assignment(reg, expr(new INative("TAG_Bool(false)", null), module.type_bool)) + add_assignment(reg, lit_false_reg) seq = iif.else_seq end # "x.==(y)" - add_assignment(reg, expr(icall, module.type_bool)) + add_assignment(reg, expr(icall, mmmodule.type_bool)) seq = seq_old return reg end @@ -159,14 +159,49 @@ class ICodeBuilder end end + # Add an escape to a given sequence + # Create a new IEscapeMark if required + fun add_escape(seq: ISeq) + do + var mark = seq.iescape_mark + if mark == null then + mark = new IEscapeMark + iroutine.escape_marks.add(mark) + seq.iescape_mark = mark + end + stmt(new IEscape(mark)) + end + + # Return a literal "null" value + fun lit_null_reg: IRegister + do + return new_register(mmmodule.type_none) + end + + # Return a literal "true" value + fun lit_true_reg: IRegister + do + var e = new IBoolValue(true) + return expr(e, mmmodule.type_bool) + end + + # Return a literal "false" value + fun lit_false_reg: IRegister + do + var e = new IBoolValue(false) + return expr(e, mmmodule.type_bool) + end + # Get a new register fun new_register(s: MMType): IRegister do - return new IRegister(s) + var r = new IRegister(s) + iroutine.registers.add(r) + return r end # The module where classes and types are extracted - readable var _module: MMModule + readable var _mmmodule: MMModule # The current iroutine build readable var _iroutine: IRoutine @@ -174,16 +209,12 @@ class ICodeBuilder # The current sequence of icodes readable writable var _seq: ISeq - # The method associated to the iroutine (if any) - readable var _method: nullable MMMethod - - init(module: MMModule, r: IRoutine, m: nullable MMMethod) + init(mod: MMModule, r: IRoutine) do - _module = module + _mmmodule = mod _current_location = r.location _iroutine = r _seq = r.body - _method = m end # New ICodes are set to this location @@ -217,16 +248,16 @@ redef class MMSignature end # Create an empty IClosureDef that match the signature - fun generate_empty_iclosuredef: IClosureDef + fun generate_empty_iclosuredef(icb: ICodeBuilder): IClosureDef do var args = new Array[IRegister] for i in [0..arity[ do - args.add(new IRegister(self[i])) + args.add(icb.new_register(self[i])) end var res: nullable IRegister = null var rtype = return_type if rtype != null then - res = new IRegister(rtype) + res = icb.new_register(rtype) end var iroutine = new IClosureDef(args, res) var clos: nullable Array[IClosureDecl] = null