📄 runtime.cc.svn-base
字号:
return Top::initial_object_prototype()->GetProperty(*key);}static Object* Runtime_ToBool(Arguments args) { NoHandleAllocation ha; ASSERT(args.length() == 1); return args[0]->ToBoolean();}// Returns the type string of a value; see ECMA-262, 11.4.3 (p 47).// Possible optimizations: put the type string into the oddballs.static Object* Runtime_Typeof(Arguments args) { NoHandleAllocation ha; Object* obj = args[0]; if (obj->IsNumber()) return Heap::number_symbol(); HeapObject* heap_obj = HeapObject::cast(obj); // typeof an undetectable object is 'undefined' if (heap_obj->map()->is_undetectable()) return Heap::undefined_symbol(); InstanceType instance_type = heap_obj->map()->instance_type(); if (instance_type < FIRST_NONSTRING_TYPE) { return Heap::string_symbol(); } switch (instance_type) { case ODDBALL_TYPE: if (heap_obj->IsTrue() || heap_obj->IsFalse()) { return Heap::boolean_symbol(); } if (heap_obj->IsNull()) { return Heap::object_symbol(); } ASSERT(heap_obj->IsUndefined()); return Heap::undefined_symbol(); case JS_FUNCTION_TYPE: return Heap::function_symbol(); default: // For any kind of object not handled above, the spec rule for // host objects gives that it is okay to return "object" return Heap::object_symbol(); }}static Object* Runtime_StringToNumber(Arguments args) { NoHandleAllocation ha; ASSERT(args.length() == 1); CONVERT_CHECKED(String, subject, args[0]); subject->TryFlatten(); return Heap::NumberFromDouble(StringToDouble(subject, ALLOW_HEX));}static Object* Runtime_StringFromCharCodeArray(Arguments args) { NoHandleAllocation ha; ASSERT(args.length() == 1); CONVERT_CHECKED(JSArray, codes, args[0]); int length = Smi::cast(codes->length())->value(); // Check if the string can be ASCII. int i; for (i = 0; i < length; i++) { Object* element = codes->GetElement(i); CONVERT_NUMBER_CHECKED(int, chr, Int32, element); if ((chr & 0xffff) > String::kMaxAsciiCharCode) break; } Object* object = NULL; if (i == length) { // The string is ASCII. object = Heap::AllocateRawAsciiString(length); } else { // The string is not ASCII. object = Heap::AllocateRawTwoByteString(length); } if (object->IsFailure()) return object; String* result = String::cast(object); for (int i = 0; i < length; i++) { Object* element = codes->GetElement(i); CONVERT_NUMBER_CHECKED(int, chr, Int32, element); result->Set(i, chr & 0xffff); } return result;}// kNotEscaped is generated by the following://// #!/bin/perl// for (my $i = 0; $i < 256; $i++) {// print "\n" if $i % 16 == 0;// my $c = chr($i);// my $escaped = 1;// $escaped = 0 if $c =~ m#[A-Za-z0-9@*_+./-]#;// print $escaped ? "0, " : "1, ";// }static bool IsNotEscaped(uint16_t character) { // Only for 8 bit characters, the rest are always escaped (in a different way) ASSERT(character < 256); static const char kNotEscaped[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; return kNotEscaped[character] != 0;}static Object* Runtime_URIEscape(Arguments args) { const char hex_chars[] = "0123456789ABCDEF"; NoHandleAllocation ha; ASSERT(args.length() == 1); CONVERT_CHECKED(String, source, args[0]); source->TryFlatten(); int escaped_length = 0; int length = source->length(); { Access<StringInputBuffer> buffer(&string_input_buffer); buffer->Reset(source); while (buffer->has_more()) { uint16_t character = buffer->GetNext(); if (character >= 256) { escaped_length += 6; } else if (IsNotEscaped(character)) { escaped_length++; } else { escaped_length += 3; } // We don't allow strings that are longer than Smi range. if (!Smi::IsValid(escaped_length)) { Top::context()->mark_out_of_memory(); return Failure::OutOfMemoryException(); } } } // No length change implies no change. Return original string if no change. if (escaped_length == length) { return source; } Object* o = Heap::AllocateRawAsciiString(escaped_length); if (o->IsFailure()) return o; String* destination = String::cast(o); int dest_position = 0; Access<StringInputBuffer> buffer(&string_input_buffer); buffer->Rewind(); while (buffer->has_more()) { uint16_t character = buffer->GetNext(); if (character >= 256) { destination->Set(dest_position, '%'); destination->Set(dest_position+1, 'u'); destination->Set(dest_position+2, hex_chars[character >> 12]); destination->Set(dest_position+3, hex_chars[(character >> 8) & 0xf]); destination->Set(dest_position+4, hex_chars[(character >> 4) & 0xf]); destination->Set(dest_position+5, hex_chars[character & 0xf]); dest_position += 6; } else if (IsNotEscaped(character)) { destination->Set(dest_position, character); dest_position++; } else { destination->Set(dest_position, '%'); destination->Set(dest_position+1, hex_chars[character >> 4]); destination->Set(dest_position+2, hex_chars[character & 0xf]); dest_position += 3; } } return destination;}static inline int TwoDigitHex(uint16_t character1, uint16_t character2) { static const signed char kHexValue['g'] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15 }; if (character1 > 'f') return -1; int hi = kHexValue[character1]; if (hi == -1) return -1; if (character2 > 'f') return -1; int lo = kHexValue[character2]; if (lo == -1) return -1; return (hi << 4) + lo;}static inline int Unescape(String* source, int i, int length, int* step) { uint16_t character = source->Get(i); int32_t hi, lo; if (character == '%' && i <= length - 6 && source->Get(i + 1) == 'u' && (hi = TwoDigitHex(source->Get(i + 2), source->Get(i + 3))) != -1 && (lo = TwoDigitHex(source->Get(i + 4), source->Get(i + 5))) != -1) { *step = 6; return (hi << 8) + lo; } else if (character == '%' && i <= length - 3 && (lo = TwoDigitHex(source->Get(i + 1), source->Get(i + 2))) != -1) { *step = 3; return lo; } else { *step = 1; return character; }}static Object* Runtime_URIUnescape(Arguments args) { NoHandleAllocation ha; ASSERT(args.length() == 1); CONVERT_CHECKED(String, source, args[0]); source->TryFlatten(); bool ascii = true; int length = source->length(); int unescaped_length = 0; for (int i = 0; i < length; unescaped_length++) { int step; if (Unescape(source, i, length, &step) > String::kMaxAsciiCharCode) ascii = false; i += step; } // No length change implies no change. Return original string if no change. if (unescaped_length == length) return source; Object* o = ascii ? Heap::AllocateRawAsciiString(unescaped_length) : Heap::AllocateRawTwoByteString(unescaped_length); if (o->IsFailure()) return o; String* destination = String::cast(o); int dest_position = 0; for (int i = 0; i < length; dest_position++) { int step; destination->Set(dest_position, Unescape(source, i, length, &step)); i += step; } return destination;}static Object* Runtime_StringParseInt(Arguments args) { NoHandleAllocation ha; CONVERT_CHECKED(String, s, args[0]); CONVERT_DOUBLE_CHECKED(n, args[1]); int radix = FastD2I(n); s->TryFlatten(); int len = s->length(); int i; // Skip leading white space. for (i = 0; i < len && Scanner::kIsWhiteSpace.get(s->Get(i)); i++) ; if (i == len) return Heap::nan_value(); // Compute the sign (default to +). int sign = 1; if (s->Get(i) == '-') { sign = -1; i++; } else if (s->Get(i) == '+') { i++; } // Compute the radix if 0. if (radix == 0) { radix = 10; if (i < len && s->Get(i) == '0') { radix = 8; if (i + 1 < len) { int c = s->Get(i + 1); if (c == 'x' || c == 'X') { radix = 16; i += 2; } } } } else if (radix == 16) { // Allow 0x or 0X prefix if radix is 16. if (i + 1 < len && s->Get(i) == '0') { int c = s->Get(i + 1); if (c == 'x' || c == 'X') i += 2; } } RUNTIME_ASSERT(2 <= radix && radix <= 36); double value; int end_index = StringToInt(s, i, radix, &value); if (end_index != i) { return Heap::NumberFromDouble(sign * value); } return Heap::nan_value();}static Object* Runtime_StringParseFloat(Arguments args) { NoHandleAllocation ha; CONVERT_CHECKED(String, str, args[0]); // ECMA-262 section 15.1.2.3, empty string is NaN double value = StringToDouble(str, ALLOW_TRAILING_JUNK, OS::nan_value()); // Create a number object from the value. return Heap::NumberFromDouble(value);}static unibrow::Mapping<unibrow::ToUppercase, 128> to_upper_mapping;static unibrow::Mapping<unibrow::ToLowercase, 128> to_lower_mapping;template <class Converter>static Object* ConvertCase(Arguments args, unibrow::Mapping<Converter, 128>* mapping) { NoHandleAllocation ha; CONVERT_CHECKED(String, s, args[0]); int raw_string_length = s->length(); // Assume that the string is not empty; we need this assumption later if (raw_string_length == 0) return s; int length = raw_string_length; s->TryFlatten(); // We try this twice, once with the assumption that the result is // no longer than the input and, if that assumption breaks, again // with the exact length. This is implemented using a goto back // to this label if we discover that the assumption doesn't hold. // I apologize sincerely for this and will give a vaffel-is to // the first person who can implement it in a nicer way. try_convert: // Allocate the resulting string. // // NOTE: This assumes that the upper/lower case of an ascii // character is also ascii. This is currently the case, but it // might break in the future if we implement more context and locale // dependent upper/lower conversions. Object* o = s->IsAscii() ? Heap::AllocateRawAsciiString(length) : Heap::AllocateRawTwoByteString(length); if (o->IsFailure()) return o; String* result = String::cast(o); bool has_changed_character = false; // Convert all characters to upper case, assuming that they will fit // in the buffer Access<StringInputBuffer> buffer(&string_input_buffer); buffer->Reset(s); unibrow::uchar chars[unibrow::kMaxCaseConvertedSize]; int i = 0; // We can assume that the string is not empty uc32 current = buffer->GetNext(); while (i < length) { uc32 next = buffer->has_more() ? buffer->GetNext() : 0; int char_length = mapping->get(current, next, chars); if (char_length == 0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -