// Shared implementation used by test and exec. bool RegExpObject::match(TiExcState* exec) { RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor(); UString input = exec->argument(0).toString(exec); TiGlobalData* globalData = &exec->globalData(); if (!regExp()->global()) { int position; int length; regExpConstructor->performMatch(*globalData, d->regExp.get(), input, 0, position, length); return position >= 0; } TiValue jsLastIndex = getLastIndex(); unsigned lastIndex; if (LIKELY(jsLastIndex.isUInt32())) { lastIndex = jsLastIndex.asUInt32(); if (lastIndex > input.length()) { setLastIndex(0); return false; } } else { double doubleLastIndex = jsLastIndex.toInteger(exec); if (doubleLastIndex < 0 || doubleLastIndex > input.length()) { setLastIndex(0); return false; } lastIndex = static_cast<unsigned>(doubleLastIndex); } int position; int length = 0; regExpConstructor->performMatch(*globalData, d->regExp.get(), input, lastIndex, position, length); if (position < 0) { setLastIndex(0); return false; } setLastIndex(position + length); return true; }
EncodedTiValue JSC_HOST_CALL numberProtoFuncToString(TiExcState* exec) { TiValue thisValue = exec->hostThisValue(); TiValue v = thisValue.getJSNumber(); if (!v) return throwVMTypeError(exec); TiValue radixValue = exec->argument(0); int radix; if (radixValue.isInt32()) radix = radixValue.asInt32(); else if (radixValue.isUndefined()) radix = 10; else radix = static_cast<int>(radixValue.toInteger(exec)); // nan -> 0 if (radix == 10) return TiValue::encode(jsString(exec, v.toString(exec))); static const char* const digits = "0123456789abcdefghijklmnopqrstuvwxyz"; // Fast path for number to character conversion. if (radix == 36) { if (v.isInt32()) { int x = v.asInt32(); if (static_cast<unsigned>(x) < 36) { // Exclude negatives TiGlobalData* globalData = &exec->globalData(); return TiValue::encode(globalData->smallStrings.singleCharacterString(globalData, digits[x])); } } } if (radix < 2 || radix > 36) return throwVMError(exec, createRangeError(exec, "toString() radix argument must be between 2 and 36")); // INT_MAX results in 1024 characters left of the dot with radix 2 // give the same space on the right side. safety checks are in place // unless someone finds a precise rule. char s[2048 + 3]; const char* lastCharInString = s + sizeof(s) - 1; double x = v.uncheckedGetNumber(); if (isnan(x) || isinf(x)) return TiValue::encode(jsString(exec, UString::number(x))); bool isNegative = x < 0.0; if (isNegative) x = -x; double integerPart = floor(x); char* decimalPoint = s + sizeof(s) / 2; // convert integer portion char* p = decimalPoint; double d = integerPart; do { int remainderDigit = static_cast<int>(fmod(d, radix)); *--p = digits[remainderDigit]; d /= radix; } while ((d <= -1.0 || d >= 1.0) && s < p); if (isNegative) *--p = '-'; char* startOfResultString = p; ASSERT(s <= startOfResultString); d = x - integerPart; p = decimalPoint; const double epsilon = 0.001; // TODO: guessed. base on radix ? bool hasFractionalPart = (d < -epsilon || d > epsilon); if (hasFractionalPart) { *p++ = '.'; do { d *= radix; const int digit = static_cast<int>(d); *p++ = digits[digit]; d -= digit; } while ((d < -epsilon || d > epsilon) && p < lastCharInString); } *p = '\0'; ASSERT(p < s + sizeof(s)); return TiValue::encode(jsString(exec, startOfResultString)); }