- v.native_array_def(pname, ret, arguments)
- return true
- end
- if pname == "exit" then
- v.add("exit({arguments[1]});")
- return true
- else if pname == "sys" then
- v.ret(v.new_expr("glob_sys", ret.as(not null)))
- return true
- else if pname == "calloc_string" then
- v.ret(v.new_expr("(char*)nit_alloc({arguments[1]})", ret.as(not null)))
- return true
- else if pname == "calloc_array" then
- v.calloc_array(ret.as(not null), arguments)
- return true
- else if pname == "object_id" then
- v.ret(v.new_expr("(long){arguments.first}", ret.as(not null)))
- return true
- else if pname == "is_same_type" then
- v.ret(v.is_same_type_test(arguments[0], arguments[1]))
- return true
- else if pname == "is_same_instance" then
- v.ret(v.equal_test(arguments[0], arguments[1]))
- return true
- else if pname == "output_class_name" then
- var nat = v.class_name_string(arguments.first)
- v.add("printf(\"%s\\n\", {nat});")
- return true
- else if pname == "native_class_name" then
- var nat = v.class_name_string(arguments.first)
- v.ret(v.new_expr("(char*){nat}", ret.as(not null)))
- return true
- else if pname == "force_garbage_collection" then
- v.add("nit_gcollect();")
- return true
- else if pname == "native_argc" then
- v.ret(v.new_expr("glob_argc", ret.as(not null)))
- return true
- else if pname == "native_argv" then
- v.ret(v.new_expr("glob_argv[{arguments[1]}]", ret.as(not null)))
- return true
- end
- return false
- end
-
- # Compile an extern method
- # Return `true` if the compilation was successful, `false` if a fall-back is needed
- fun compile_externmeth_to_c(v: AbstractCompilerVisitor, mpropdef: MMethodDef, arguments: Array[RuntimeVariable]): Bool
- do
- var externname
- var at = self.get_single_annotation("extern", v.compiler.modelbuilder)
- if at != null and at.n_args.length == 1 then
- externname = at.arg_as_string(v.compiler.modelbuilder)
- if externname == null then return false
- else
- return false
- end
- v.add_extern(mpropdef.mclassdef.mmodule)
- var res: nullable RuntimeVariable = null
- var ret = mpropdef.msignature.return_mtype
- if ret != null then
- ret = v.resolve_for(ret, arguments.first)
- res = v.new_var_extern(ret)
- end
- v.adapt_signature(mpropdef, arguments)
- v.unbox_signature_extern(mpropdef, arguments)
-
- if res == null then
- v.add("{externname}({arguments.join(", ")});")
- else
- v.add("{res} = {externname}({arguments.join(", ")});")
- res = v.box_extern(res, ret.as(not null))
- v.ret(res)
- end
- return true
- end
-
- # Compile an extern factory
- # Return `true` if the compilation was successful, `false` if a fall-back is needed
- fun compile_externinit_to_c(v: AbstractCompilerVisitor, mpropdef: MMethodDef, arguments: Array[RuntimeVariable]): Bool
- do
- var externname
- var at = self.get_single_annotation("extern", v.compiler.modelbuilder)
- if at != null then
- externname = at.arg_as_string(v.compiler.modelbuilder)
- if externname == null then return false
- else
- return false
- end
- v.add_extern(mpropdef.mclassdef.mmodule)
- v.adapt_signature(mpropdef, arguments)
- v.unbox_signature_extern(mpropdef, arguments)
- var ret = arguments.first.mtype
- var res = v.new_var_extern(ret)
-
- arguments.shift
-
- v.add("{res} = {externname}({arguments.join(", ")});")
- res = v.box_extern(res, ret)
- v.ret(res)
- return true
- end
-end
-
-redef class AAttrPropdef
- redef fun can_inline: Bool do return not is_lazy
-
- redef fun compile_to_c(v, mpropdef, arguments)
- do
- if mpropdef == mreadpropdef then
- assert arguments.length == 1
- var recv = arguments.first
- var res
- if is_lazy then
- var set
- var ret = self.mtype
- var useiset = not ret.is_c_primitive and not ret isa MNullableType
- var guard = self.mlazypropdef.mproperty
- if useiset then
- set = v.isset_attribute(self.mpropdef.mproperty, recv)
- else
- set = v.read_attribute(guard, recv)
- end
- v.add("if(likely({set})) \{")
- res = v.read_attribute(self.mpropdef.mproperty, recv)
+ return v.native_array_def(pname, ret, arguments)
+ else if cname == "Int8" then
+ if pname == "output" then
+ v.add("printf(\"%\"PRIi8 \"\\n\", {arguments.first});")
+ return true
+ else if pname == "object_id" then
+ v.ret(v.new_expr("(long){arguments.first}", ret.as(not null)))
+ return true
+ else if pname == "+" then
+ v.ret(v.new_expr("{arguments[0]} + {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "-" then
+ v.ret(v.new_expr("{arguments[0]} - {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "unary -" then
+ v.ret(v.new_expr("-{arguments[0]}", ret.as(not null)))
+ return true
+ else if pname == "unary +" then
+ v.ret(arguments[0])
+ return true
+ else if pname == "*" then
+ v.ret(v.new_expr("{arguments[0]} * {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "/" then
+ v.ret(v.new_expr("{arguments[0]} / {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "%" then
+ v.ret(v.new_expr("{arguments[0]} % {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "<<" then
+ v.ret(v.new_expr("{arguments[0]} << {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == ">>" then
+ v.ret(v.new_expr("{arguments[0]} >> {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "==" then
+ v.ret(v.equal_test(arguments[0], arguments[1]))
+ return true
+ else if pname == "!=" then
+ var res = v.equal_test(arguments[0], arguments[1])
+ v.ret(v.new_expr("!{res}", ret.as(not null)))
+ return true
+ else if pname == "<" then
+ v.ret(v.new_expr("{arguments[0]} < {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == ">" then
+ v.ret(v.new_expr("{arguments[0]} > {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "<=" then
+ v.ret(v.new_expr("{arguments[0]} <= {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == ">=" then
+ v.ret(v.new_expr("{arguments[0]} >= {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "to_i" then
+ v.ret(v.new_expr("(long){arguments[0]}", ret.as(not null)))
+ return true
+ else if pname == "to_b" then
+ v.ret(v.new_expr("(unsigned char){arguments[0]}", ret.as(not null)))
+ return true
+ else if pname == "to_i16" then
+ v.ret(v.new_expr("(int16_t){arguments[0]}", ret.as(not null)))
+ return true
+ else if pname == "to_u16" then
+ v.ret(v.new_expr("(uint16_t){arguments[0]}", ret.as(not null)))
+ return true
+ else if pname == "to_i32" then
+ v.ret(v.new_expr("(int32_t){arguments[0]}", ret.as(not null)))
+ return true
+ else if pname == "to_u32" then
+ v.ret(v.new_expr("(uint32_t){arguments[0]}", ret.as(not null)))
+ return true
+ else if pname == "to_f" then
+ v.ret(v.new_expr("(double){arguments[0]}", ret.as(not null)))
+ return true
+ else if pname == "&" then
+ v.ret(v.new_expr("{arguments[0]} & {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "|" then
+ v.ret(v.new_expr("{arguments[0]} | {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "^" then
+ v.ret(v.new_expr("{arguments[0]} ^ {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "unary ~" then
+ v.ret(v.new_expr("~{arguments[0]}", ret.as(not null)))
+ return true
+ end
+ else if cname == "Int16" then
+ if pname == "output" then
+ v.add("printf(\"%\"PRIi16 \"\\n\", {arguments.first});")
+ return true
+ else if pname == "object_id" then
+ v.ret(v.new_expr("(long){arguments.first}", ret.as(not null)))
+ return true
+ else if pname == "+" then
+ v.ret(v.new_expr("{arguments[0]} + {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "-" then
+ v.ret(v.new_expr("{arguments[0]} - {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "unary -" then
+ v.ret(v.new_expr("-{arguments[0]}", ret.as(not null)))
+ return true
+ else if pname == "unary +" then
+ v.ret(arguments[0])
+ return true
+ else if pname == "*" then
+ v.ret(v.new_expr("{arguments[0]} * {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "/" then
+ v.ret(v.new_expr("{arguments[0]} / {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "%" then
+ v.ret(v.new_expr("{arguments[0]} % {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "<<" then
+ v.ret(v.new_expr("{arguments[0]} << {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == ">>" then
+ v.ret(v.new_expr("{arguments[0]} >> {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "==" then
+ v.ret(v.equal_test(arguments[0], arguments[1]))
+ return true
+ else if pname == "!=" then
+ var res = v.equal_test(arguments[0], arguments[1])
+ v.ret(v.new_expr("!{res}", ret.as(not null)))
+ return true
+ else if pname == "<" then
+ v.ret(v.new_expr("{arguments[0]} < {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == ">" then
+ v.ret(v.new_expr("{arguments[0]} > {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "<=" then
+ v.ret(v.new_expr("{arguments[0]} <= {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == ">=" then
+ v.ret(v.new_expr("{arguments[0]} >= {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "to_i" then
+ v.ret(v.new_expr("(long){arguments[0]}", ret.as(not null)))
+ return true
+ else if pname == "to_b" then
+ v.ret(v.new_expr("(unsigned char){arguments[0]}", ret.as(not null)))
+ return true
+ else if pname == "to_i8" then
+ v.ret(v.new_expr("(int8_t){arguments[0]}", ret.as(not null)))
+ return true
+ else if pname == "to_u16" then
+ v.ret(v.new_expr("(uint16_t){arguments[0]}", ret.as(not null)))
+ return true
+ else if pname == "to_i32" then
+ v.ret(v.new_expr("(int32_t){arguments[0]}", ret.as(not null)))
+ return true
+ else if pname == "to_u32" then
+ v.ret(v.new_expr("(uint32_t){arguments[0]}", ret.as(not null)))
+ return true
+ else if pname == "to_f" then
+ v.ret(v.new_expr("(double){arguments[0]}", ret.as(not null)))
+ return true
+ else if pname == "&" then
+ v.ret(v.new_expr("{arguments[0]} & {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "|" then
+ v.ret(v.new_expr("{arguments[0]} | {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "^" then
+ v.ret(v.new_expr("{arguments[0]} ^ {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "unary ~" then
+ v.ret(v.new_expr("~{arguments[0]}", ret.as(not null)))
+ return true
+ end
+ else if cname == "UInt16" then
+ if pname == "output" then
+ v.add("printf(\"%\"PRIu16 \"\\n\", {arguments.first});")
+ return true
+ else if pname == "object_id" then
+ v.ret(v.new_expr("(long){arguments.first}", ret.as(not null)))
+ return true
+ else if pname == "+" then
+ v.ret(v.new_expr("{arguments[0]} + {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "-" then
+ v.ret(v.new_expr("{arguments[0]} - {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "unary -" then
+ v.ret(v.new_expr("-{arguments[0]}", ret.as(not null)))
+ return true
+ else if pname == "unary +" then
+ v.ret(arguments[0])
+ return true
+ else if pname == "*" then
+ v.ret(v.new_expr("{arguments[0]} * {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "/" then
+ v.ret(v.new_expr("{arguments[0]} / {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "%" then
+ v.ret(v.new_expr("{arguments[0]} % {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "<<" then
+ v.ret(v.new_expr("{arguments[0]} << {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == ">>" then
+ v.ret(v.new_expr("{arguments[0]} >> {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "==" then
+ v.ret(v.equal_test(arguments[0], arguments[1]))
+ return true
+ else if pname == "!=" then
+ var res = v.equal_test(arguments[0], arguments[1])
+ v.ret(v.new_expr("!{res}", ret.as(not null)))
+ return true
+ else if pname == "<" then
+ v.ret(v.new_expr("{arguments[0]} < {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == ">" then
+ v.ret(v.new_expr("{arguments[0]} > {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "<=" then
+ v.ret(v.new_expr("{arguments[0]} <= {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == ">=" then
+ v.ret(v.new_expr("{arguments[0]} >= {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "to_i" then
+ v.ret(v.new_expr("(long){arguments[0]}", ret.as(not null)))
+ return true
+ else if pname == "to_b" then
+ v.ret(v.new_expr("(unsigned char){arguments[0]}", ret.as(not null)))
+ return true
+ else if pname == "to_i8" then
+ v.ret(v.new_expr("(int8_t){arguments[0]}", ret.as(not null)))
+ return true
+ else if pname == "to_i16" then
+ v.ret(v.new_expr("(int16_t){arguments[0]}", ret.as(not null)))
+ return true
+ else if pname == "to_i32" then
+ v.ret(v.new_expr("(int32_t){arguments[0]}", ret.as(not null)))
+ return true
+ else if pname == "to_u32" then
+ v.ret(v.new_expr("(uint32_t){arguments[0]}", ret.as(not null)))
+ return true
+ else if pname == "to_f" then
+ v.ret(v.new_expr("(double){arguments[0]}", ret.as(not null)))
+ return true
+ else if pname == "&" then
+ v.ret(v.new_expr("{arguments[0]} & {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "|" then
+ v.ret(v.new_expr("{arguments[0]} | {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "^" then
+ v.ret(v.new_expr("{arguments[0]} ^ {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "unary ~" then
+ v.ret(v.new_expr("~{arguments[0]}", ret.as(not null)))
+ return true
+ end
+ else if cname == "Int32" then
+ if pname == "output" then
+ v.add("printf(\"%\"PRIi32 \"\\n\", {arguments.first});")
+ return true
+ else if pname == "object_id" then
+ v.ret(v.new_expr("(long){arguments.first}", ret.as(not null)))
+ return true
+ else if pname == "+" then
+ v.ret(v.new_expr("{arguments[0]} + {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "-" then
+ v.ret(v.new_expr("{arguments[0]} - {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "unary -" then
+ v.ret(v.new_expr("-{arguments[0]}", ret.as(not null)))
+ return true
+ else if pname == "unary +" then
+ v.ret(arguments[0])
+ return true
+ else if pname == "*" then
+ v.ret(v.new_expr("{arguments[0]} * {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "/" then
+ v.ret(v.new_expr("{arguments[0]} / {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "%" then
+ v.ret(v.new_expr("{arguments[0]} % {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "<<" then
+ v.ret(v.new_expr("{arguments[0]} << {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == ">>" then
+ v.ret(v.new_expr("{arguments[0]} >> {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "==" then
+ v.ret(v.equal_test(arguments[0], arguments[1]))
+ return true
+ else if pname == "!=" then
+ var res = v.equal_test(arguments[0], arguments[1])
+ v.ret(v.new_expr("!{res}", ret.as(not null)))
+ return true
+ else if pname == "<" then
+ v.ret(v.new_expr("{arguments[0]} < {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == ">" then
+ v.ret(v.new_expr("{arguments[0]} > {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "<=" then
+ v.ret(v.new_expr("{arguments[0]} <= {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == ">=" then
+ v.ret(v.new_expr("{arguments[0]} >= {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "to_i" then
+ v.ret(v.new_expr("(long){arguments[0]}", ret.as(not null)))
+ return true
+ else if pname == "to_b" then
+ v.ret(v.new_expr("(unsigned char){arguments[0]}", ret.as(not null)))
+ return true
+ else if pname == "to_i8" then
+ v.ret(v.new_expr("(int8_t){arguments[0]}", ret.as(not null)))
+ return true
+ else if pname == "to_i16" then
+ v.ret(v.new_expr("(int16_t){arguments[0]}", ret.as(not null)))
+ return true
+ else if pname == "to_u16" then
+ v.ret(v.new_expr("(uint16_t){arguments[0]}", ret.as(not null)))
+ return true
+ else if pname == "to_u32" then
+ v.ret(v.new_expr("(uint32_t){arguments[0]}", ret.as(not null)))
+ return true
+ else if pname == "to_f" then
+ v.ret(v.new_expr("(double){arguments[0]}", ret.as(not null)))
+ return true
+ else if pname == "&" then
+ v.ret(v.new_expr("{arguments[0]} & {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "|" then
+ v.ret(v.new_expr("{arguments[0]} | {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "^" then
+ v.ret(v.new_expr("{arguments[0]} ^ {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "unary ~" then
+ v.ret(v.new_expr("~{arguments[0]}", ret.as(not null)))
+ return true
+ end
+ else if cname == "UInt32" then
+ if pname == "output" then
+ v.add("printf(\"%\"PRIu32 \"\\n\", {arguments.first});")
+ return true
+ else if pname == "object_id" then
+ v.ret(v.new_expr("(long){arguments.first}", ret.as(not null)))
+ return true
+ else if pname == "+" then
+ v.ret(v.new_expr("{arguments[0]} + {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "-" then
+ v.ret(v.new_expr("{arguments[0]} - {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "unary -" then
+ v.ret(v.new_expr("-{arguments[0]}", ret.as(not null)))
+ return true
+ else if pname == "unary +" then
+ v.ret(arguments[0])
+ return true
+ else if pname == "*" then
+ v.ret(v.new_expr("{arguments[0]} * {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "/" then
+ v.ret(v.new_expr("{arguments[0]} / {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "%" then
+ v.ret(v.new_expr("{arguments[0]} % {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "<<" then
+ v.ret(v.new_expr("{arguments[0]} << {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == ">>" then
+ v.ret(v.new_expr("{arguments[0]} >> {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "==" then
+ v.ret(v.equal_test(arguments[0], arguments[1]))
+ return true
+ else if pname == "!=" then
+ var res = v.equal_test(arguments[0], arguments[1])
+ v.ret(v.new_expr("!{res}", ret.as(not null)))
+ return true
+ else if pname == "<" then
+ v.ret(v.new_expr("{arguments[0]} < {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == ">" then
+ v.ret(v.new_expr("{arguments[0]} > {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "<=" then
+ v.ret(v.new_expr("{arguments[0]} <= {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == ">=" then
+ v.ret(v.new_expr("{arguments[0]} >= {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "to_i" then
+ v.ret(v.new_expr("(long){arguments[0]}", ret.as(not null)))
+ return true
+ else if pname == "to_b" then
+ v.ret(v.new_expr("(unsigned char){arguments[0]}", ret.as(not null)))
+ return true
+ else if pname == "to_i8" then
+ v.ret(v.new_expr("(int8_t){arguments[0]}", ret.as(not null)))
+ return true
+ else if pname == "to_i16" then
+ v.ret(v.new_expr("(int16_t){arguments[0]}", ret.as(not null)))
+ return true
+ else if pname == "to_u16" then
+ v.ret(v.new_expr("(uint16_t){arguments[0]}", ret.as(not null)))
+ return true
+ else if pname == "to_i32" then
+ v.ret(v.new_expr("(int32_t){arguments[0]}", ret.as(not null)))
+ return true
+ else if pname == "to_f" then
+ v.ret(v.new_expr("(double){arguments[0]}", ret.as(not null)))
+ return true
+ else if pname == "&" then
+ v.ret(v.new_expr("{arguments[0]} & {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "|" then
+ v.ret(v.new_expr("{arguments[0]} | {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "^" then
+ v.ret(v.new_expr("{arguments[0]} ^ {arguments[1]}", ret.as(not null)))
+ return true
+ else if pname == "unary ~" then
+ v.ret(v.new_expr("~{arguments[0]}", ret.as(not null)))
+ return true
+ end
+ end
+ if pname == "exit" then
+ v.add("exit({arguments[1]});")
+ return true
+ else if pname == "sys" then
+ v.ret(v.new_expr("glob_sys", ret.as(not null)))
+ return true
+ else if pname == "object_id" then
+ v.ret(v.new_expr("(long){arguments.first}", ret.as(not null)))
+ return true
+ else if pname == "is_same_type" then
+ v.ret(v.is_same_type_test(arguments[0], arguments[1]))
+ return true
+ else if pname == "is_same_instance" then
+ v.ret(v.equal_test(arguments[0], arguments[1]))
+ return true
+ else if pname == "output_class_name" then
+ var nat = v.class_name_string(arguments.first)
+ v.add("printf(\"%s\\n\", {nat});")
+ return true
+ else if pname == "native_class_name" then
+ var nat = v.class_name_string(arguments.first)
+ v.ret(v.new_expr("(char*){nat}", ret.as(not null)))
+ return true
+ else if pname == "force_garbage_collection" then
+ v.add("nit_gcollect();")
+ return true
+ else if pname == "native_argc" then
+ v.ret(v.new_expr("glob_argc", ret.as(not null)))
+ return true
+ else if pname == "native_argv" then
+ v.ret(v.new_expr("glob_argv[{arguments[1]}]", ret.as(not null)))
+ return true
+ end
+ return false
+ end
+
+ # Compile an extern method
+ # Return `true` if the compilation was successful, `false` if a fall-back is needed
+ fun compile_externmeth_to_c(v: AbstractCompilerVisitor, mpropdef: MMethodDef, arguments: Array[RuntimeVariable]): Bool
+ do
+ var externname
+ var at = self.get_single_annotation("extern", v.compiler.modelbuilder)
+ if at != null and at.n_args.length == 1 then
+ externname = at.arg_as_string(v.compiler.modelbuilder)
+ if externname == null then return false
+ else
+ return false
+ end
+ v.add_extern(mpropdef.mclassdef.mmodule)
+ var res: nullable RuntimeVariable = null
+ var ret = mpropdef.msignature.return_mtype
+ if ret != null then
+ ret = v.resolve_for(ret, arguments.first)
+ res = v.new_var_extern(ret)
+ end
+ v.adapt_signature(mpropdef, arguments)
+ v.unbox_signature_extern(mpropdef, arguments)
+
+ if res == null then
+ v.add("{externname}({arguments.join(", ")});")
+ else
+ v.add("{res} = {externname}({arguments.join(", ")});")
+ res = v.box_extern(res, ret.as(not null))
+ v.ret(res)
+ end
+ return true
+ end
+
+ # Compile an extern factory
+ # Return `true` if the compilation was successful, `false` if a fall-back is needed
+ fun compile_externinit_to_c(v: AbstractCompilerVisitor, mpropdef: MMethodDef, arguments: Array[RuntimeVariable]): Bool
+ do
+ var externname
+ var at = self.get_single_annotation("extern", v.compiler.modelbuilder)
+ if at != null then
+ externname = at.arg_as_string(v.compiler.modelbuilder)
+ if externname == null then return false
+ else
+ return false
+ end
+ v.add_extern(mpropdef.mclassdef.mmodule)
+ v.adapt_signature(mpropdef, arguments)
+ v.unbox_signature_extern(mpropdef, arguments)
+ var ret = arguments.first.mtype
+ var res = v.new_var_extern(ret)
+
+ arguments.shift
+
+ v.add("{res} = {externname}({arguments.join(", ")});")
+ res = v.box_extern(res, ret)
+ v.ret(res)
+ return true
+ end
+end
+
+redef class AAttrPropdef
+ redef fun can_inline: Bool do return not is_lazy
+
+ redef fun compile_to_c(v, mpropdef, arguments)
+ do
+ if mpropdef == mreadpropdef then
+ assert arguments.length == 1
+ var recv = arguments.first
+ var res
+ if is_lazy then
+ var set
+ var ret = self.mtype
+ var useiset = not ret.is_c_primitive and not ret isa MNullableType
+ var guard = self.mlazypropdef.mproperty
+ if useiset then
+ set = v.isset_attribute(self.mpropdef.mproperty, recv)
+ else
+ set = v.read_attribute(guard, recv)
+ end
+ v.add("if(likely({set})) \{")
+ res = v.read_attribute(self.mpropdef.mproperty, recv)