Merge remote-tracking branch 'origin/sk-rpc' into al-rpc

This commit is contained in:
Ari Lazier 2015-10-07 22:20:52 -06:00
commit d09e345399
4 changed files with 40 additions and 36 deletions

View File

@ -272,6 +272,7 @@ static JSGlobalContextRef s_context;
return @{ return @{
@"type": @(RJSTypeGet(realm::PropertyTypeArray).c_str()), @"type": @(RJSTypeGet(realm::PropertyTypeArray).c_str()),
@"id": @(oid), @"id": @(oid),
@"size": @(array->link_view->size()),
@"schema": [self objectSchemaToJSONObject:array->object_schema] @"schema": [self objectSchemaToJSONObject:array->object_schema]
}; };
} }

View File

@ -5,7 +5,7 @@ let util = require('./util');
let idKey = Symbol(); let idKey = Symbol();
let realmKey = Symbol(); let realmKey = Symbol();
let prototype = util.createListPrototype(getterForLength, getterForIndex, setterForIndex); let prototype = {};
exports.create = create; exports.create = create;
@ -15,9 +15,7 @@ exports.create = create;
'push', 'push',
'unshift', 'unshift',
'splice', 'splice',
].forEach(function(name, i) { ].forEach(function(name) {
let growthMethod = (i >= 2);
Object.defineProperty(prototype, name, { Object.defineProperty(prototype, name, {
value: function() { value: function() {
let listId = this[idKey]; let listId = this[idKey];
@ -28,11 +26,7 @@ exports.create = create;
} }
let result = rpc.callListMethod(realmId, listId, name, Array.from(arguments)); let result = rpc.callListMethod(realmId, listId, name, Array.from(arguments));
this[util.resizeListKey]();
// Since this method might have grown the list, ensure index properties are defined.
if (growthMethod) {
prototype[util.growListPrototypeKey](this.length);
}
return result; return result;
} }
@ -40,13 +34,13 @@ exports.create = create;
}); });
function create(realmId, info) { function create(realmId, info) {
let list = Object.create(prototype); let list = util.createList(prototype, getterForLength, getterForIndex, setterForIndex);
let size = info.size; let size = info.size;
list[realmKey] = realmId; list[realmKey] = realmId;
list[idKey] = info.id; list[idKey] = info.id;
list[util.growListPrototypeKey](size); list[util.resizeListKey](size);
return list; return list;
} }

View File

@ -5,18 +5,17 @@ let util = require('./util');
let idKey = Symbol(); let idKey = Symbol();
let realmKey = Symbol(); let realmKey = Symbol();
let prototype = util.createListPrototype(getterForLength, getterForIndex);
exports.create = create; exports.create = create;
function create(realmId, info) { function create(realmId, info) {
let results = Object.create(prototype); let results = util.createList(null, getterForLength, getterForIndex);
let size = info.size; let size = info.size;
results[realmKey] = realmId; results[realmKey] = realmId;
results[idKey] = info.resultsId; results[idKey] = info.resultsId;
results[util.growListPrototypeKey](size); results[util.resizeListKey](size);
return results; return results;
} }

View File

@ -1,35 +1,45 @@
'use strict'; 'use strict';
let growListPrototypeKey = exports.growListPrototypeKey = Symbol(); let resizeListKey = exports.resizeListKey = Symbol();
exports.createListPrototype = createListPrototype; exports.createList = createList;
function createListPrototype(getterForLength, getterForIndex, setterForIndex) { function createList(prototype, getterForLength, getterForIndex, setterForIndex) {
let prototype = {}; var list = prototype ? Object.create(prototype) : {};
let maxSize = 0; var size = 0;
Object.defineProperty(prototype, 'length', { Object.defineProperty(list, 'length', {get: getterForLength});
get: getterForLength
});
prototype[growListPrototypeKey] = function(size) { list[resizeListKey] = function(length) {
if (size < maxSize) { if (length == null) {
length = this.length;
}
if (length == size) {
return; return;
} }
let props = {}; if (length > size) {
for (let i = maxSize; i <= size; i++) { let props = {};
props[i] = {
get: getterForIndex(i), for (let i = size; i < length; i++) {
set: setterForIndex && setterForIndex(i), props[i] = {
}; get: getterForIndex(i),
set: setterForIndex && setterForIndex(i),
enumerable: true,
configurable: true,
};
}
Object.defineProperties(this, props);
}
else if (length < size) {
for (let i = size - 1; i >= length; i--) {
delete this[i];
}
} }
// TODO: Use ES6 Proxy once it's supported on Chrome! size = length;
Object.defineProperties(prototype, props); };
maxSize = size + 1; return list;
}
return prototype;
} }