ESBase unshift(Call eval, int length) throws Throwable { ESObject obj = eval.getArg(-1).toObject(); ESBase lenObj = obj.getProperty(LENGTH); int len = lenObj.toInt32(); if (len < 0) len = 0; if (length == 0) return ESNumber.create(0); for (int i = len - 1; i >= 0; i--) { ESBase value = obj.getProperty(i); if (value == null) obj.delete(ESString.create(length + i)); else obj.setProperty(length + i, value); } for (int i = 0; i < length; i++) { ESBase value = eval.getArg(i); if (value == null) obj.delete(ESString.create(i)); else obj.setProperty(i, value); } ESNumber numLen = ESNumber.create(len + length); obj.setProperty(LENGTH, numLen); return numLen; }
ESBase slice(Call eval, int length) throws Throwable { ESObject obj = eval.getArg(-1).toObject(); ESBase lenObj = obj.getProperty(LENGTH); int len = lenObj.toInt32(); ESArray array = Global.getGlobalProto().createArray(); if (len <= 0) return array; int start = 0; if (length > 0) start = eval.getArg(0).toInt32(); if (start < 0) start += len; if (start < 0) start = 0; if (start > len) return array; int end = len; if (length > 1) end = eval.getArg(1).toInt32(); if (end < 0) end += len; if (end < 0) return array; if (end > len) end = len; if (start >= end) return array; for (int i = 0; i < end - start; i++) { ESBase value = obj.hasProperty(start + i); if (value != null) array.setProperty(i, value); } array.setProperty(LENGTH, ESNumber.create(end - start)); return array; }
ESBase join(Call eval, int length) throws Throwable { String separator = length == 0 ? "," : eval.getArg(0).toString(); ESObject array = eval.getArg(-1).toObject(); return join(array, separator); }
ESBase push(Call eval, int length) throws Throwable { ESObject obj = eval.getArg(-1).toObject(); ESBase lenObj = obj.getProperty(LENGTH); int len = lenObj.toInt32(); if (len < 0) len = 0; for (int i = 0; i < length; i++) obj.setProperty(len + i, eval.getArg(i)); ESNumber newLen = ESNumber.create(len + length); obj.setProperty(LENGTH, newLen); return newLen; }
ESBase splice(Call eval, int length) throws Throwable { if (length < 2) return esUndefined; ESObject obj = eval.getArg(-1).toObject(); int index = eval.getArg(0).toInt32(); int count = eval.getArg(1).toInt32(); boolean single = count == 1; ESBase lenObj = obj.getProperty(LENGTH); int len = lenObj.toInt32(); if (index < 0) index += len; if (index < 0) index = 0; if (count < 0) count = 0; if (index + count > len) count = len - index; ESBase value; if (count < 1) value = esUndefined; else { value = Global.getGlobalProto().createArray(); for (int i = 0; i < count; i++) value.setProperty(i, obj.getProperty(index + i)); } int delta = length - 2 - count; if (delta < 0) { for (int i = 0; i < len - count; i++) { ESBase temp = obj.getProperty(i + index + count); if (temp == null) obj.delete(ESString.create(i + index + count + delta)); else obj.setProperty(i + index + count + delta, temp); } } else if (delta > 0) { for (int i = len - count - 1; i >= 0; i--) { ESBase temp = obj.getProperty(i + index + count); if (temp == null) obj.delete(ESString.create(i + index + count + delta)); else obj.setProperty(i + index + count + delta, temp); } } for (int i = 0; i < length - 2; i++) obj.setProperty(i + index, eval.getArg(i + 2)); obj.setProperty(LENGTH, ESNumber.create(len - count + length - 2)); return value; }
ESBase concat(Call eval, int length) throws Throwable { ESArray array = Global.getGlobalProto().createArray(); int k = 0; for (int i = -1; i < length; i++) { ESBase arg = eval.getArg(i); if (arg == esNull || arg == esUndefined || arg == esEmpty) continue; ESBase arglen = arg.hasProperty(LENGTH); if (arglen == null) { array.setProperty(k++, arg); continue; } int len = (int) arglen.toInt32(); if (len < 0) { array.setProperty(k++, arg); continue; } for (int j = 0; j < len; j++) { ESBase obj = arg.hasProperty(j); if (obj != null) array.setProperty(k, obj); k++; } } array.setProperty(LENGTH, ESNumber.create(k)); return array; }
ESBase create(Call eval, int length) throws Throwable { ESObject obj = Global.getGlobalProto().createArray(); if (length == 0) return obj; if (length == 1) { ESBase arg = eval.getArg(0); if (arg instanceof ESNumber) obj.setProperty(LENGTH, ESNumber.create(arg.toInt32())); else obj.setProperty(0, arg); return obj; } for (int i = 0; i < length; i++) obj.setProperty(i, eval.getArg(i)); return obj; }
ESBase sort(Call eval, int length) throws Throwable { ESObject array = eval.getArg(-1).toObject(); ESBase cmp = length == 0 ? null : eval.getArg(0); int len = (int) array.getProperty(LENGTH).toInt32(); ESBase[] values = new ESBase[len]; for (int i = 0; i < len; i++) values[i] = array.getProperty("" + i); qsort(values, 0, len, cmp); for (int i = 0; i < len; i++) { if (values[i] == esUndefined) array.delete("" + i); else array.setProperty("" + i, values[i]); } return array; }
ESBase pop(Call eval, int length) throws Throwable { ESObject obj = eval.getArg(-1).toObject(); ESBase lenObj = obj.hasProperty(LENGTH); int len; if (lenObj == null || (len = lenObj.toInt32()) <= 0) return esUndefined; ESBase value = obj.getProperty(len - 1); obj.setProperty(LENGTH, ESNumber.create(len - 1)); return value; }
ESBase shift(Call eval, int length) throws Throwable { ESObject obj = eval.getArg(-1).toObject(); ESBase lenObj = obj.hasProperty(LENGTH); int len; if (lenObj == null || (len = (int) lenObj.toInt32()) <= 0) return esUndefined; ESBase value = obj.getProperty(0); for (int i = 1; i < len; i++) { ESBase temp = obj.hasProperty(i); if (temp == null) obj.delete(ESString.create(i - 1)); else obj.setProperty(i - 1, temp); } obj.setProperty(LENGTH, ESNumber.create(len - 1)); return value; }
ESBase reverse(Call eval, int length) throws Throwable { ESObject array = eval.getArg(-1).toObject(); int len = (int) array.getProperty(LENGTH).toInt32(); for (int k = 0; k < len / 2; k++) { int firstIndex = k; int secondIndex = len - k - 1; ESBase first = array.hasProperty(firstIndex); ESBase second = array.hasProperty(secondIndex); if (first == null) array.delete(secondIndex); else array.setProperty(secondIndex, first); if (second == null) array.delete(firstIndex); else array.setProperty(firstIndex, second); } return array; }
// XXX: different for non-js1.2 ESBase toString(Call eval, int length) throws Throwable { ESObject array = eval.getArg(-1).toObject(); return toString(array); }