protected fun calloc_array(size: Int): NativeArray[E] is intern
end
-# Native C array (void ...).
+# Native Nit array
+# Access are unchecked and it has a fixed size
+# Not for public use: may become private.
universal NativeArray[E]
+ # The length of the array
+ fun length: Int is intern
+ # Use `self` to initialize a standard Nit Array.
+ fun to_a: Array[E] do return new Array[E].with_native(self, length)
fun [](index: Int): E is intern
fun []=(index: Int, item: E) is intern
fun copy_to(dest: NativeArray[E], length: Int) is intern
if mtype.mclass.name == "NativeArray" then
# NativeArrays are just a instance header followed by an array of values
+ v.add_decl("int length;")
v.add_decl("{mtype.arguments.first.ctype} values[1];")
end
if is_native_array then
var mtype_elt = mtype.arguments.first
v.add("{res} = nit_alloc(sizeof(struct {mtype.c_name}) + length*sizeof({mtype_elt.ctype}));")
+ v.add("((struct {mtype.c_name}*){res})->length = length;")
else
v.add("{res} = nit_alloc(sizeof(struct {mtype.c_name}));")
end
else if pname == "[]=" then
self.add("{recv}[{arguments[1]}]={arguments[2]};")
return
+ else if pname == "length" then
+ self.ret(self.new_expr("((struct {arguments[0].mcasttype.c_name}*){arguments[0]})->length", ret_type.as(not null)))
+ return
else if pname == "copy_to" then
var recv1 = "((struct {arguments[1].mcasttype.c_name}*){arguments[1]})->values"
self.add("memcpy({recv1},{recv},{arguments[2]}*sizeof({elttype.ctype}));")
else if pname == "[]=" then
recvval[args[1].to_i] = args[2]
return null
+ else if pname == "length" then
+ return v.int_instance(recvval.length)
else if pname == "copy_to" then
recvval.copy(0, args[2].to_i, args[1].val.as(Array[Instance]), 0)
return null
self.header.add_decl("struct instance_{c_instance_name} \{")
self.header.add_decl("const struct type *type;")
self.header.add_decl("const struct class *class;")
- # NativeArrays are just a instance header followed by an array of values
+ # NativeArrays are just a instance header followed by a length and an array of values
+ self.header.add_decl("int length;")
self.header.add_decl("val* values[0];")
self.header.add_decl("\};")
self.provide_declaration("NEW_{c_name}", "{mtype.ctype} NEW_{c_name}(int length, const struct type* type);")
v.add_decl("/* allocate {mtype} */")
v.add_decl("{mtype.ctype} NEW_{c_name}(int length, const struct type* type) \{")
- var res = v.new_named_var(mtype, "self")
- res.is_exact = true
+ var res = v.get_name("self")
+ v.add_decl("struct instance_{c_instance_name} *{res};")
var mtype_elt = mtype.arguments.first
v.add("{res} = nit_alloc(sizeof(struct instance_{c_instance_name}) + length*sizeof({mtype_elt.ctype}));")
v.add("{res}->type = type;")
hardening_live_type(v, "type")
v.require_declaration("class_{c_name}")
v.add("{res}->class = &class_{c_name};")
- v.add("return {res};")
+ v.add("{res}->length = length;")
+ v.add("return (val*){res};")
v.add("\}")
return
end
else if pname == "[]=" then
self.add("{recv}[{arguments[1]}]={arguments[2]};")
return
+ else if pname == "length" then
+ self.ret(self.new_expr("((struct instance_{nclass.c_instance_name}*){arguments[0]})->length", ret_type.as(not null)))
+ return
else if pname == "copy_to" then
var recv1 = "((struct instance_{nclass.c_instance_name}*){arguments[1]})->values"
self.add("memcpy({recv1}, {recv}, {arguments[2]}*sizeof({elttype.ctype}));")
#Build instance struct
self.header.add_decl("struct instance_{c_name} \{")
self.header.add_decl("const struct class *class;")
+ self.header.add_decl("int length;")
self.header.add_decl("val* values[];")
self.header.add_decl("\};")
self.provide_declaration("NEW_{c_name}", "{mtype.ctype} NEW_{c_name}(int length);")
v.add_decl("/* allocate {mtype} */")
v.add_decl("{mtype.ctype} NEW_{c_name}(int length) \{")
- var res = v.new_named_var(mtype, "self")
- res.is_exact = true
+ var res = v.get_name("self")
+ v.add_decl("struct instance_{c_name} *{res};")
var mtype_elt = mtype.arguments.first
v.add("{res} = nit_alloc(sizeof(struct instance_{c_name}) + length*sizeof({mtype_elt.ctype}));")
v.require_declaration("class_{c_name}")
v.add("{res}->class = &class_{c_name};")
- v.add("return {res};")
+ v.add("{res}->length = length;")
+ v.add("return (val*){res};")
v.add("\}")
return
end
--- /dev/null
+3
+10
+20
+30
+10
+20
+30
--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+class Toto
+ super ArrayCapable[Int]
+
+ fun toto
+ do
+ var a = calloc_array(3)
+ a[0] = 10
+ a[1] = 20
+ a[2] = 30
+ a.length.output
+ a.to_a.output
+ (new Array[Int].with_native(a, 3)).output
+ end
+end
+
+(new Toto).toto