[t][TT#1509] Prevent core dumps by preventing negative length array creation. Tests...
[parrot.git] / t / pmc / fixedpmcarray.t
blob9886f690ae651cc822d6cde6cf5d248c65e16a56
1 #! parrot
2 # Copyright (C) 2001-2010, Parrot Foundation.
3 # $Id$
5 =head1 NAME
7 t/pmc/fixedpmcarray.t - FixedPMCArray PMC
9 =head1 SYNOPSIS
11     % prove t/pmc/fixedpmcarray.t
13 =head1 DESCRIPTION
15 Tests C<FixedPMCArray> PMC. Checks size, sets various elements, including
16 out-of-bounds test. Checks INT and PMC keys.
18 =cut
20 .sub main :main
21     .include 'test_more.pir'
22     plan(82)
23     test_setting_array_size()
24     test_assign_from_another()
25     test_assign_self()
26     test_assign_non_array()
27     test_resize_exception()
28     test_truthiness()
29     test_tt991()
30     test_tt1039()
31     test_setting_first_elem()
32     test_setting_second_elem()
33     test_negative_index()
34     test_oob_elem()
35     test_set_pmc_keys_access_ints()
36     test_set_ints_access_pmc_keys()
37     test_interface()
38     test_get_uninitialized()
39     test_get_null_elem()
40     test_definedness()
41     test_splice_oob()
42     test_get_repr()
43     test_elements()
44     test_equality()
45     test_multi_keys()
46     test_splice()
47     test_sort()
48     test_exists()
49     test_new_style_init()
50     test_invalid_init_tt1509()
51 .end
53 .sub test_exists
54     .local pmc fpa
55     fpa = new ['FixedPMCArray']
56     fpa = 5
57     $I0 = exists fpa[3]
58     nok($I0,'FixedPMCArray element existence')
59     fpa[2] = 42
60     $I0 = exists fpa[2]
61     ok($I0,'FixedPMCArray element existence')
63     new $P1, ['Key']
64     set $P1, 0
65     fpa[$P1] = 99
66     $I0 = exists fpa[$P1]
67     ok($I0,'FixedPMCArray element existence')
68 .end
70 .sub test_sort
71      .local pmc compares, cmp_fun
72      # TT #1317 doesnt work wit prederef of JIT
73      bounds 1
74      compares = new ['Integer']
75      compares = 0
76      set_global "compares", compares
77      cmp_fun = get_global "cmp_fun"
78      sort_ar()
79      sort_ar(cmp_fun)
80 .end
82 # this is used by test_sort
83 .sub sort_ar
84     .param pmc cmp_fun :optional
85     .local pmc compares
86     compares = get_global "compares"
87     compares = 0
88     .local pmc array
89     array = new ['FixedPMCArray']
90     array = 5
91     array[0] = 10
92     array[1] = 2
93     array[2] = 5
94     array[3] = 9
95     array[4] = 1
96     array."sort"(cmp_fun)
97     ok(1,'call sort on FixedPMCArray')
99     .local pmc test1
100     test1 = new ['FixedPMCArray']
101     test1 = 5
102     test1[0] = 1
103     test1[1] = 2
104     test1[2] = 5
105     test1[3] = 9
106     test1[4] = 10
108     is_deeply( array, test1 )
110 .end
112 # this is used by test_sort
113 .sub cmp_fun
114     .param pmc a
115     .param pmc b
116     $I0 = cmp a, b
117     .local pmc compares
118     compares = get_global "compares"
119     inc compares
120     .begin_return
121     .set_return $I0
122     .end_return
123 .end
125 .sub test_splice
126     .local pmc one
127     .local pmc test1, test2, test3
128     one = new ['Integer']
129     one = 1
131     .local pmc fpa
132     fpa = new ['FixedPMCArray']
133     fpa = 5
135     splice fpa, one, 0, 5
136     test1 = new ['FixedPMCArray']
137     test1 = 5
138     test1[0] = 1
139     test1[1] = 1
140     test1[2] = 1
141     test1[3] = 1
142     test1[4] = 1
144     is_deeply(fpa, test1 )
146     .local pmc two
147     two = new ['Integer']
148     two = 2
150     splice fpa, two, 1, 3
151     test2 = new ['FixedPMCArray']
152     test2 = 5
153     test2[0] = 1
154     test2[1] = 2
155     test2[2] = 2
156     test2[3] = 2
157     test2[4] = 1
158     is_deeply(fpa, test2 )
160     .local pmc three
161     three = new ['Integer']
162     three = 3
164     splice fpa, three, 2, 3
165     test3 = new ['FixedPMCArray']
166     test3 = 5
167     test3[0] = 1
168     test3[1] = 2
169     test3[2] = 3
170     test3[3] = 3
171     test3[4] = 3
172     is_deeply(fpa, test3 )
173 .end
175 .sub test_multi_keys
176     .local pmc    matrix, row
177     .local pmc    elem_in_pmc
178     .local pmc    elem_out_pmc
179     .local int    elem_out_int
180     .local num    elem_out_num
181     .local string elem_out_string
183     matrix = new ['FixedPMCArray']
184     matrix = 1
185     row = new ['FixedPMCArray']
186     row = 4           # set the size by assigning an integer, number or pmc
187     matrix[0] = row
188     matrix[0;0] = 128
189     matrix[0;1] = 128.128
190     elem_in_pmc = new ['Integer']
191     elem_in_pmc = 256
192     matrix[0;2] = elem_in_pmc
193     matrix[0;3] = "asdf"
195     elem_out_int = matrix[0;0]
196     is(elem_out_int,128)
198     elem_out_pmc = matrix[0;0]
199     is(elem_out_pmc,128)
201     elem_out_num = matrix[0;0]
202     is(elem_out_num,128)
204     elem_out_string = matrix[0;0]
205     is(elem_out_string,128)
207     elem_out_pmc = matrix[0;1]
208     is(elem_out_pmc,"128.128")
210     elem_out_num = matrix[0;1]
211     is(elem_out_num,"128.128")
213     elem_out_string = matrix[0;1]
214     is(elem_out_string,"128.128")
216     elem_out_int = matrix[0;2]
217     is(elem_out_int,256)
219     elem_out_pmc = matrix[0;2]
220     is(elem_out_pmc,256)
222     elem_out_num = matrix[0;2]
223     is(elem_out_num,256)
225     elem_out_string = matrix[0;2]
226     is(elem_out_string,256)
228     elem_out_int = matrix[0;0]
229     is(elem_out_int,128)
231     elem_out_pmc = matrix[0;0]
232     is(elem_out_pmc,128)
234     elem_out_num = matrix[0;0]
235     is(elem_out_num,128)
237     elem_out_string = matrix[0;0]
238     is(elem_out_string,128)
240 .end
242 .sub test_equality
243     .local pmc fpa1, fpa2, p1, p2
244     .local int i
245     fpa1 = new ['FixedPMCArray']
246     fpa2 = new ['FixedPMCArray']
248     is(fpa1,fpa2)
250     fpa1 = 3
251     isnt(fpa1,fpa2)
253     fpa2 = 3
255     p1 = new ['String']
256     p1 = "foobarx"
257     p2 = new ['String']
258     p2 = "foobarx"
260     fpa1[0] = p1
261     fpa2[0] = p2
263     is(fpa1,fpa2)
265     p1 = new ['String']
266     p2 = new ['String']
267     p1 = ''
268     p2 = ''
270     fpa1[1] = p1
272     isnt(fpa1,fpa2)
274     fpa2[1] = p2
276     is(fpa1,fpa2)
278 .end
280 .sub test_elements
281     .local pmc arr1
282     .local int elems_i
283     .local num elems_f
284     arr1 = new ['FixedPMCArray']
285     arr1 = 0
286     elems_i = elements arr1
287     is(elems_i,0)
289     elems_i = arr1
290     is(elems_i,0)
292     elems_f = arr1
293     is(elems_f,0)
295     arr1 = new ['FixedPMCArray']
296     arr1 = 2048
297     elems_i = elements arr1
298     is(elems_i,2048)
300     elems_i = arr1
301     is(elems_i,2048)
303     elems_f = arr1
304     is(elems_f,2048)
305 .end
307 .sub test_get_repr
308     .local string s, aux
309     s = get_repr_fpa_n(0)
310     aux = get_repr_fpa_n(1)
311     concat s, aux
312     aux = get_repr_fpa_n(2)
313     concat s, aux
314     aux = get_repr_fpa_n(3)
315     concat s, aux
316     substring(s,'()(0)(0, 1)(0, 1, 2)','get_repr')
317 .end
319 .sub get_repr_fpa_n
320     .param int n
321     .local int i
322     .local pmc fpa, p
323     .local string s
324     fpa = new ['FixedPMCArray']
325     fpa = n
326     i = 0
327 next:
328     if i == n goto done
329     p = box i
330     fpa[i] = p
331     inc i
332     goto next
333 done:
334     s = get_repr fpa
335     .return(s)
336 .end
338 .sub test_splice_oob
339     throws_substring(<<'CODE','FixedPMCArray: index out of bounds','splice oob, offset 0')
340     .sub main
341         .local pmc fpa
342         fpa = new ['FixedPMCArray']
343         fpa = 5
345         .local pmc nil
346         nil = new ['Undef']
348         splice fpa, nil, 0, 6
349     .end
350 CODE
351     throws_substring(<<'CODE','FixedPMCArray: index out of bounds','splice oob, big offset')
352     .sub main
353         .local pmc fpa
354         fpa = new ['FixedPMCArray']
355         fpa = 5
357         .local pmc nil
358         nil = new ['Undef']
360         splice fpa, nil, 6, 0
361     .end
362 CODE
363 .end
365 .sub test_definedness
366     .local pmc arr1
367     arr1 = new ['FixedPMCArray']
368     arr1 = 2005
369     .local int defined_elem_1956
370     defined_elem_1956 = defined arr1[1956]
371     is(defined_elem_1956,0,'definedness')
372     arr1[1956] = 42
373     defined_elem_1956 = defined arr1[1956]
374     is(defined_elem_1956,1,'definedness')
375     .local pmc val
376     null val
377     arr1[1956] = val
378     defined_elem_1956 = defined arr1[1956]
379     is(defined_elem_1956,0,'definedness')
380 .end
382 .sub test_get_null_elem
383   .local pmc arr1, n
384   .local int i
385   .local string s
386   arr1 = new ['FixedPMCArray']
387   arr1 = 1
388   arr1[0] = n
389   i = arr1[0]
390   is(i,0,'null int is 0')
391   s = arr1[0]
392   is(s,"",'null string is empty string')
393 .end
395 .sub test_get_uninitialized
396     throws_substring(<<'CODE','Null PMC access in name','get uninitialized')
397     .sub main
398         .local pmc arr1
399         arr1 = new ['FixedPMCArray']
400         arr1 = 2005
401         .local pmc elem_1956
402         elem_1956 = arr1[1956]
403         .local string type_1956
404         type_1956 = typeof elem_1956
405         print type_1956
406     .end
407 CODE
408 .end
410 .sub test_interface
411     .local pmc pmc1
412     pmc1 = new ['FixedPMCArray']
413     .local int bool1
414     does bool1, pmc1, "scalar"
415     nok(bool1,'FixedPMCArray does not scalar')
416     does bool1, pmc1, "array"
417     ok(bool1,'FixedPMCArray does array')
418     does bool1, pmc1, "no_interface"
419     nok(bool1,'no interface')
420 .end
421 .sub test_set_ints_access_pmc_keys
422      new $P0, ['FixedPMCArray']
423      set $P0, 1024
425      set $P0[25], 125
426      set $P0[128], 10.2
427      set $P0[513], "cow"
428      new $P1, ['Integer']
429      set $P1, 123456
430      set $P0[1023], $P1
432      new $P2, ['Key']
433      set $P2, 25
434      set $I0, $P0[$P2]
435      is($I0, 125,'got int with pmc key')
437      set $P2, 128
438      set $N0, $P0[$P2]
439      is($N0,10.2,'got float with pmc key',0.00001)
441      set $P2, 513
442      set $S0, $P0[$P2]
443      is($S0, "cow", 'got string with pmc key')
445      set $P2, 1023
446      set $P3, $P0[$P2]
447      set $I1, $P3
448      is($I1, 123456, 'got another int with pmc key')
449 .end
451 .sub test_set_pmc_keys_access_ints
452      new $P0, ['FixedPMCArray']
453      set $P0, 3
454      new $P1, ['Key']
456      set $P1, 0
457      set $P0[$P1], 25
459      set $P1, 1
460      set $P0[$P1], 2.5
462      set $P1, 2
463      set $P0[$P1], "bleep"
465      set $I0, $P0[0]
466      is($I0, 25,'got integer with int lookup')
467      set $N0, $P0[1]
468      is($N0,2.5,'got float with int lookup',0.00001)
470      set $S0, $P0[2]
471      is($S0, "bleep",'got string with int lookup')
472 .end
474 .sub test_oob_elem
475     throws_substring(<<'CODE','FixedPMCArray: index out of bounds!','set out-of-bounds index')
476         .sub main
477             new $P0, ['FixedPMCArray']
478             set $P0, 1
479             set $P0[1], -7
480         .end
481 CODE
482     throws_substring(<<'CODE','FixedPMCArray: index out of bounds!','set out-of-bounds index')
483         .sub main
484             new $P0, ['FixedPMCArray']
485             set $P0, 1
486             set $I0, $P0[1]
487         .end
488 CODE
490 .end
492 .sub test_negative_index
493     throws_substring(<<'CODE','FixedPMCArray: index out of bounds!','set negative index')
494 .sub main
495     new $P0, ['FixedPMCArray']
496     set $P0, 1
497     set $P0[-1], -7
498 .end
499 CODE
500     throws_substring(<<'CODE','FixedPMCArray: index out of bounds!','get negative index')
501 .sub main
502     new $P0, ['FixedPMCArray']
503     set $P0, 1
504     set $I0, $P0[-1]
505 .end
506 CODE
508 .end
510 .sub test_setting_second_elem
511     new $P0, ['FixedPMCArray']
512     set $P0, 2
514     set $P0[1],-7
515     set $I0,$P0[1]
516     is($I0,-7,'set second elem to int')
518     set $P0[1],3.7
519     set $N0,$P0[1]
520     is($N0,3.7,'set second elem to float')
522     set $P0[1],"muwhahaha"
523     set $S0,$P0[1]
524     is($S0,"muwhahaha",'set second elem to string')
525 .end
527 .sub test_setting_first_elem
528     new $P0, ['FixedPMCArray']
529     set $P0, 1
531     set $P0[0],-7
532     set $I0,$P0[0]
533     is($I0,-7,'set first elem to int')
535     set $P0[0],3.7
536     set $N0,$P0[0]
537     is($N0,3.7,'set first elem to float')
539     set $P0[0],"muwhahaha"
540     set $S0,$P0[0]
541     is($S0,"muwhahaha",'set first elem to string')
542 .end
544 .sub test_truthiness
545     new $P0, ['FixedPMCArray']
546     set $P0, 0
547     nok($P0,'length 0 FixedPMCArray is falsey')
548     set $P0, 1
549     ok($P0, 'length 1 FixedPMCArray is truthy')
550 .end
552 .sub test_tt991
553     throws_substring(<<'CODE','FixedPMCArray: Cannot set array size to a negative number','cannot create a negative length array')
554         .sub main
555             new $P0, ['FixedPMCArray']
556             set $P0, -1
557         .end
558 CODE
559 .end
561 .sub test_tt1039
562     .local pmc arr
563     arr = new 'FixedPMCArray'
564     arr = 4
565     arr[0] = 'just'
566     arr[1] = 'another'
567     arr[2] = 'perl'
568     arr[3] = 'hacker'
570     .local pmc sorted_arr
571     sorted_arr = new 'FixedPMCArray'
572     sorted_arr = 4
573     sorted_arr[0] = 'another'
574     sorted_arr[1] = 'hacker'
575     sorted_arr[2] = 'just'
576     sorted_arr[3] = 'perl'
578     $P0 = get_global 'cmpfn1'
579     $P1 = clone arr
580     $P1.'sort'($P0)
581     is_deeply($P1, sorted_arr, 'fpa.sort called with normal Sub')
583     $P0 = get_global 'cmpfn2'
584     $P1 = clone arr
585     $P1.'sort'($P0)
586     is_deeply($P1, sorted_arr, 'fpa.sort called with MultiSub')
587 .end
589 .sub 'cmpfn1'
590     .param pmc a
591     .param pmc b
592     $I0 = cmp_str a, b
593     .return ($I0)
594 .end
596 .sub 'cmpfn2' :multi(_, _)
597     .param pmc a
598     .param pmc b
599     $I0 = cmp_str a, b
600     .return ($I0)
601 .end
603 .sub test_resize_exception
604     throws_substring(<<'CODE',"FixedPMCArray: Can't resize",'cannot resize FixedPMCArray')
605         .sub main
606             new $P0, ['FixedPMCArray']
607             set $I0,$P0
608             set $P0,1
609             set $P0,2
610         .end
611 CODE
613     throws_substring(<<'CODE',"set_number_native() not implemented in class 'FixedPMCArray'", 'cannot use float as length to FixedPMCArray')
614         .sub main
615             new $P0, ['FixedPMCArray']
616             set $P0, 42.0
617         .end
618 CODE
620     throws_substring(<<'CODE',"set_string_native() not implemented in class 'FixedPMCArray'", 'cannot use string as length to FixedPMCArray')
621         .sub main
622             new $P0, ['FixedPMCArray']
623             set $P0,"GIGO"
624         .end
625 CODE
626 .end
628 .sub test_assign_non_array
629     throws_substring(<<'CODE', "Can't set self from this type",'assign from non-array')
630     .sub main
631         .local pmc arr, other
632         .local int n
633         arr = new ['FixedPMCArray']
634         other = new ['Integer']
635         assign arr, other
636     .end
637 CODE
638 .end
640 .sub test_assign_self
641     .local pmc arr
642     arr = new ['FixedPMCArray']
643     assign arr, arr
644     ok(1, 'Can assign FixedPMCArray to itself')
645 .end
647 .sub test_assign_from_another
648     .local pmc arr1, arr2
649     .local int n
650     arr1 = new ['FixedPMCArray']
651     arr1 = 32
652     arr2 = new ['FixedPMCArray']
653     arr2 = 15
654     assign arr1, arr2
655     n = arr1
656     is(n,15,'assigning to FixedPMCArray from another FixedPMCArray')
657 .end
659 .sub test_setting_array_size
660     new $P0, ['FixedPMCArray']
662     set $I0, $P0
663     is($I0,0,'size of new FixedPMCArray is 0')
665     set $P0, 1
666     set $I0, $P0
668     is($I0,1,'size of FixedPMCArray is 1')
669 .end
671 .sub 'test_new_style_init'
672     $P0 = new 'FixedPMCArray', 10
674     $I0 = $P0
675     is($I0, 10, "New style init creates the correct # of elements")
677     $P0 = new ['FixedPMCArray'], 10
679     $I0 = $P0
680     is($I0, 10, "New style init creates the correct # of elements for a key constant")
681 .end
683 .sub test_invalid_init_tt1509
684     throws_substring(<<'CODE', 'Cannot set array size to a negative number (-10)', 'New style init does not dump core for negative array lengths')
685     .sub main
686         $P0 = new ['FixedPMCArray'], -10
687     .end
688 CODE
690     throws_substring(<<'CODE', 'Cannot set array size to a negative number (-10)', 'New style init (key constant) does not dump core for negative array lengths')
691     .sub main
692         $P0 = new 'FixedPMCArray', -10
693     .end
694 CODE
695 .end
697 # Local Variables:
698 #   mode: pir
699 #   fill-column: 100
700 # End:
701 # vim: expandtab shiftwidth=4 ft=pir: