Skip to content

Commit 05ea592

Browse files
authored
Merge pull request #106 from sqreen/feature/array_growth
Fix array conversion when size changes dynamically
2 parents d5b0829 + 627b547 commit 05ea592

File tree

2 files changed

+86
-3
lines changed

2 files changed

+86
-3
lines changed

py_mini_racer/extension/mini_racer_extension.cc

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -447,20 +447,23 @@ static BinaryValue *convert_v8_to_binary(Isolate * isolate,
447447

448448
else if (value->IsArray()) {
449449
Local<Array> arr = Local<Array>::Cast(value);
450-
size_t len = arr->Length();
450+
uint32_t len = arr->Length();
451+
451452
BinaryValue **ary = xalloc(ary, sizeof(*ary) * len);
452453

453454
res->type = type_array;
454455
res->array_val = ary;
456+
res->len = (size_t) len;
455457

456-
for(uint32_t i = 0; i < arr->Length(); i++) {
458+
for(uint32_t i = 0; i < len; i++) {
457459
Local<Value> element = arr->Get(context, i).ToLocalChecked();
458460
BinaryValue *bin_value = convert_v8_to_binary(isolate, context, element);
459461
if (bin_value == NULL) {
462+
// adjust final array length
463+
res->len = (size_t) i;
460464
goto err;
461465
}
462466
ary[i] = bin_value;
463-
res->len++;
464467
}
465468
}
466469

tests/test_array_growth.py

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
#!/usr/bin/env python
2+
# -*- coding: utf-8 -*-
3+
4+
""" Growing and reducing arrays """
5+
6+
import unittest
7+
import json
8+
import time
9+
10+
from datetime import datetime
11+
12+
from py_mini_racer import py_mini_racer
13+
14+
15+
class Test(unittest.TestCase):
16+
""" Test basic types """
17+
18+
19+
def setUp(self):
20+
21+
self.mr = py_mini_racer.MiniRacer()
22+
23+
def test_growing_array(self):
24+
25+
js = """
26+
var global_array = [
27+
{
28+
get first() {
29+
for(var i=0; i<100; i++) {
30+
global_array.push(0x41);
31+
}
32+
}
33+
}
34+
];
35+
36+
// when accessed, the first element will make the array grow by 100 items.
37+
global_array;
38+
"""
39+
40+
res = self.mr.eval(js)
41+
# Initial array size was 100
42+
self.assertEqual(res, [{'first': None}])
43+
44+
45+
def test_shrinking_array(self):
46+
js = """
47+
var global_array = [
48+
{
49+
get first() {
50+
for(var i=0; i<100; i++) {
51+
global_array.pop();
52+
}
53+
}
54+
}
55+
];
56+
57+
// build a 200 elements array
58+
for(var i=0; i < 200; i++)
59+
global_array.push(0x41);
60+
61+
// when the first item will be accessed, it should remove 100 items.
62+
63+
global_array;
64+
"""
65+
66+
# The final array should have:
67+
# The initial item
68+
# The next 100 items (value 0x41)
69+
# The last 100 items which have been removed when the initial key was accessed
70+
array = [{'first': None}] + \
71+
[0x41] * 100 + \
72+
[None] * 100
73+
74+
res = self.mr.eval(js)
75+
self.assertEqual(res, array)
76+
77+
78+
if __name__ == '__main__':
79+
import sys
80+
sys.exit(unittest.main())

0 commit comments

Comments
 (0)