in runtime/under-builtins-module.cpp [3175:3248]
static RawObject intFromByteslike(Thread* thread, const Byteslike& byteslike,
word length, word base) {
DCHECK_BOUND(length, byteslike.length());
DCHECK(base == 0 || (base >= 2 && base <= 36), "invalid base");
if (length <= 0) return Error::error();
// Clamp the length at the last whitespace character.
word idx = length;
byte b = byteslike.byteAt(--idx);
while (ASCII::isSpace(b)) {
if (idx <= 0) return Error::error();
b = byteslike.byteAt(--idx);
}
length = idx + 1;
// Start the index from the first non-zero whitespace character.
idx = 0;
if (idx >= length) return Error::error();
b = byteslike.byteAt(idx++);
while (ASCII::isSpace(b)) {
if (idx >= length) return Error::error();
b = byteslike.byteAt(idx++);
}
word sign = 1;
switch (b) {
case '-':
sign = -1;
// fall through
case '+':
if (idx >= length) return Error::error();
b = byteslike.byteAt(idx++);
break;
}
word inferred_base = 10;
if (b == '0') {
if (idx >= length) return SmallInt::fromWord(0);
inferred_base = inferBase(byteslike.byteAt(idx));
if (base == 0) base = inferred_base;
if (inferred_base != 10 && base == inferred_base) {
if (++idx >= length) return Error::error();
b = byteslike.byteAt(idx++);
}
} else if (base == 0) {
base = 10;
}
Runtime* runtime = thread->runtime();
HandleScope scope(thread);
Int result(&scope, SmallInt::fromWord(0));
Int digit(&scope, SmallInt::fromWord(0));
Int base_obj(&scope, SmallInt::fromWord(base));
word num_start = idx;
for (;;) {
if (b == '_') {
// No leading underscores unless the number has a prefix
if (idx == num_start && inferred_base == 10) return Error::error();
// No trailing underscores
if (idx >= length) return Error::error();
b = byteslike.byteAt(idx++);
}
word digit_val = digitValue(b, base);
if (digit_val == -1) return Error::error();
digit = Int::cast(SmallInt::fromWord(digit_val));
result = runtime->intAdd(thread, result, digit);
if (idx >= length) break;
b = byteslike.byteAt(idx++);
result = runtime->intMultiply(thread, result, base_obj);
}
if (sign < 0) {
result = runtime->intNegate(thread, result);
}
return *result;
}