nit: add native NativeString::system
[nit.git] / src / naive_interpreter.nit
index 9cda9a4..03df69f 100644 (file)
@@ -218,6 +218,7 @@ private class NaiveInterpreter
        fun native_string_instance(txt: String): Instance
        do
                var val = new Buffer.from(txt)
+               val.add('\0')
                var ic = self.mainmodule.get_primitive_class("NativeString")
                return new PrimitiveInstance[Buffer](ic.mclass_type, val)
        end
@@ -274,7 +275,7 @@ private class NaiveInterpreter
                                vararg.add(rawargs[i+1])
                        end
                        # FIXME: its it to late to determine the vararg type, this should have been done during a previous analysis
-                       var elttype = mpropdef.msignature.parameter_mtypes[vararg_rank].anchor_to(self.mainmodule, args.first.mtype.as(MClassType))
+                       var elttype = mpropdef.msignature.mparameters[vararg_rank].mtype.anchor_to(self.mainmodule, args.first.mtype.as(MClassType))
                        args.add(self.array_instance(vararg, elttype))
 
                        for i in [vararg_lastrank+1..rawargs.length-1[ do
@@ -622,13 +623,37 @@ redef class AInternMethPropdef
                else if cname == "NativeString" then
                        var recvval = args.first.val.as(Buffer)
                        if pname == "[]" then
-                               return v.char_instance(recvval[args[1].to_i])
+                               var arg1 = args[1].to_i
+                               if arg1 >= recvval.length or arg1 < 0 then
+                                       debug("Illegal access on {recvval} for element {arg1}/{recvval.length}")
+                               end
+                               return v.char_instance(recvval[arg1])
                        else if pname == "[]=" then
-                               recvval[args[1].to_i] = args[2].val.as(Char)
+                               var arg1 = args[1].to_i
+                               if arg1 >= recvval.length or arg1 < 0 then
+                                       debug("Illegal access on {recvval} for element {arg1}/{recvval.length}")
+                               end
+                               recvval[arg1] = args[2].val.as(Char)
                                return null
                        else if pname == "copy_to" then
                                # sig= copy_to(dest: NativeString, length: Int, from: Int, to: Int)
-                               recvval.copy(args[3].to_i, args[2].to_i, args[1].val.as(Buffer), args[4].to_i)
+                               var destval = args[1].val.as(Buffer)
+                               var lenval = args[2].to_i
+                               var fromval = args[3].to_i
+                               var toval = args[4].to_i
+                               if fromval < 0 then
+                                       debug("Illegal access on {recvval} for element {fromval}/{recvval.length}")
+                               end
+                               if fromval + lenval >= recvval.length then
+                                       debug("Illegal access on {recvval} for element {fromval}+{lenval}/{recvval.length}")
+                               end
+                               if toval < 0 then
+                                       debug("Illegal access on {destval} for element {toval}/{destval.length}")
+                               end
+                               if toval + lenval >= destval.length then
+                                       debug("Illegal access on {destval} for element {toval}+{lenval}/{destval.length}")
+                               end
+                               recvval.copy(fromval, lenval, destval, toval)
                                return null
                        else if pname == "atoi" then
                                return v.int_instance(recvval.to_i)
@@ -638,7 +663,7 @@ redef class AInternMethPropdef
                else if cname == "NativeArray" then
                        var recvval = args.first.val.as(Array[Instance])
                        if pname == "[]" then
-                               if args[1].to_i >= recvval.length then
+                               if args[1].to_i >= recvval.length or args[1].to_i < 0 then
                                        debug("Illegal access on {recvval} for element {args[1].to_i}/{recvval.length}")
                                end
                                return recvval[args[1].to_i]
@@ -697,7 +722,13 @@ redef class AExternMethPropdef
        do
                var pname = mpropdef.mproperty.name
                var cname = mpropdef.mclassdef.mclass.name
-               if cname == "NativeFile" then
+               if cname == "Int" then
+                       var recvval = args.first.val.as(Int)
+                       if pname == "rand" then
+                               var res = recvval.rand
+                               return v.int_instance(res)
+                       end
+               else if cname == "NativeFile" then
                        var recvval = args.first.val
                        if pname == "io_write" then
                                var a1 = args[1].val.as(Buffer)
@@ -720,8 +751,11 @@ redef class AExternMethPropdef
                                recvval.to_s.mkdir
                                return null
                        else if pname == "get_environ" then
-                               var txt = args.first.val.as(Buffer).to_s.to_symbol.environ
+                               var txt = recvval.to_s.environ
                                return v.native_string_instance(txt)
+                       else if pname == "system" then
+                               var res = sys.system(recvval.to_s)
+                               return v.int_instance(res)
                        end
                else if pname == "native_argc" then
                        return v.int_instance(v.arguments.length)