📄 runtime.cc.svn-base
字号:
return f->shared()->GetSourceCode();}static Object* Runtime_FunctionGetScriptSourcePosition(Arguments args) { NoHandleAllocation ha; ASSERT(args.length() == 1); CONVERT_CHECKED(JSFunction, fun, args[0]); int pos = fun->shared()->start_position(); return Smi::FromInt(pos);}static Object* Runtime_FunctionSetInstanceClassName(Arguments args) { NoHandleAllocation ha; ASSERT(args.length() == 2); CONVERT_CHECKED(JSFunction, fun, args[0]); CONVERT_CHECKED(String, name, args[1]); fun->SetInstanceClassName(name); return Heap::undefined_value();}static Object* Runtime_FunctionSetLength(Arguments args) { NoHandleAllocation ha; ASSERT(args.length() == 2); CONVERT_CHECKED(JSFunction, fun, args[0]); CONVERT_CHECKED(Smi, length, args[1]); fun->shared()->set_length(length->value()); return length;}static Object* Runtime_FunctionSetPrototype(Arguments args) { NoHandleAllocation ha; ASSERT(args.length() == 2); CONVERT_CHECKED(JSFunction, fun, args[0]); Object* obj = Accessors::FunctionSetPrototype(fun, args[1], NULL); if (obj->IsFailure()) return obj; return args[0]; // return TOS}static Object* Runtime_SetCode(Arguments args) { HandleScope scope; ASSERT(args.length() == 2); CONVERT_CHECKED(JSFunction, raw_target, args[0]); Handle<JSFunction> target(raw_target); Handle<Object> code = args.at<Object>(1); Handle<Context> context(target->context()); if (!code->IsNull()) { RUNTIME_ASSERT(code->IsJSFunction()); Handle<JSFunction> fun = Handle<JSFunction>::cast(code); SetExpectedNofProperties(target, fun->shared()->expected_nof_properties()); if (!fun->is_compiled() && !CompileLazy(fun, KEEP_EXCEPTION)) { return Failure::Exception(); } // Set the code, formal parameter count, and the length of the target // function. target->set_code(fun->code()); target->shared()->set_length(fun->shared()->length()); target->shared()->set_formal_parameter_count( fun->shared()->formal_parameter_count()); // Set the source code of the target function. target->shared()->set_script(fun->shared()->script()); target->shared()->set_start_position(fun->shared()->start_position()); target->shared()->set_end_position(fun->shared()->end_position()); context = Handle<Context>(fun->context()); // Make sure we get a fresh copy of the literal vector to avoid // cross context contamination. int number_of_literals = fun->NumberOfLiterals(); Handle<FixedArray> literals = Factory::NewFixedArray(number_of_literals, TENURED); if (number_of_literals > 0) { // Insert the object, regexp and array functions in the literals // array prefix. These are the functions that will be used when // creating object, regexp and array literals. literals->set(JSFunction::kLiteralGlobalContextIndex, context->global_context()); } target->set_literals(*literals); } target->set_context(*context); return *target;}static Object* CharCodeAt(String* subject, Object* index) { uint32_t i = 0; if (!Array::IndexFromObject(index, &i)) return Heap::nan_value(); // Flatten the string. If someone wants to get a char at an index // in a cons string, it is likely that more indices will be // accessed. subject->TryFlatten(); if (i >= static_cast<uint32_t>(subject->length())) return Heap::nan_value(); return Smi::FromInt(subject->Get(i));}static Object* Runtime_StringCharCodeAt(Arguments args) { NoHandleAllocation ha; ASSERT(args.length() == 2); CONVERT_CHECKED(String, subject, args[0]); Object* index = args[1]; return CharCodeAt(subject, index);}static Object* Runtime_CharFromCode(Arguments args) { NoHandleAllocation ha; ASSERT(args.length() == 1); uint32_t code; if (Array::IndexFromObject(args[0], &code)) { if (code <= 0xffff) { return Heap::LookupSingleCharacterStringFromCode(code); } } return Heap::empty_string();}static inline void ComputeKMPNextTable(String* pattern, int next_table[]) { int i = 0; int j = -1; next_table[0] = -1; Access<StringInputBuffer> buffer(&string_input_buffer); buffer->Reset(pattern); int length = pattern->length(); uint16_t p = buffer->GetNext(); while (i < length - 1) { while (j > -1 && p != pattern->Get(j)) { j = next_table[j]; } i++; j++; p = buffer->GetNext(); if (p == pattern->Get(j)) { next_table[i] = next_table[j]; } else { next_table[i] = j; } }}static Object* Runtime_StringIndexOf(Arguments args) { NoHandleAllocation ha; ASSERT(args.length() == 3); CONVERT_CHECKED(String, sub, args[0]); CONVERT_CHECKED(String, pat, args[1]); Object* index = args[2]; sub->TryFlatten(); pat->TryFlatten(); int subject_length = sub->length(); int pattern_length = pat->length(); uint32_t start_index; if (!Array::IndexFromObject(index, &start_index)) return Smi::FromInt(-1); if (pattern_length == 0) return Smi::FromInt(start_index); // Searching for one specific character is common. For one // character patterns the KMP algorithm is guaranteed to slow down // the search, so we just run through the subject string. if (pattern_length == 1) { uint16_t pattern_char = pat->Get(0); for (int i = start_index; i < subject_length; i++) { if (sub->Get(i) == pattern_char) { return Smi::FromInt(i); } } return Smi::FromInt(-1); } // For small searches, KMP is not worth the setup overhead. if (subject_length < 100) { // We know our pattern is at least 2 characters, we cache the first so // the common case of the first character not matching is faster. uint16_t pattern_first_char = pat->Get(0); for (int i = start_index; i + pattern_length <= subject_length; i++) { if (sub->Get(i) != pattern_first_char) continue; for (int j = 1; j < pattern_length; j++) { if (pat->Get(j) != sub->Get(j + i)) break; if (j == pattern_length - 1) return Smi::FromInt(i); } } return Smi::FromInt(-1); } // For patterns with a larger length we use the KMP algorithm. // // Compute the 'next' table. int* next_table = NewArray<int>(pattern_length); ComputeKMPNextTable(pat, next_table); // Search using the 'next' table. int pattern_index = 0; // We would like to use StringInputBuffer here, but it does not have // the ability to start anywhere but the first character of a // string. It would be nice to have efficient forward-seeking // support on StringInputBuffers. int subject_index = start_index; while (subject_index < subject_length) { uint16_t subject_char = sub->Get(subject_index); while (pattern_index > -1 && pat->Get(pattern_index) != subject_char) { pattern_index = next_table[pattern_index]; } pattern_index++; subject_index++; if (pattern_index >= pattern_length) { DeleteArray(next_table); return Smi::FromInt(subject_index - pattern_index); } } DeleteArray(next_table); return Smi::FromInt(-1);}static Object* Runtime_StringLastIndexOf(Arguments args) { NoHandleAllocation ha; ASSERT(args.length() == 3); CONVERT_CHECKED(String, sub, args[0]); CONVERT_CHECKED(String, pat, args[1]); Object* index = args[2]; sub->TryFlatten(); pat->TryFlatten(); uint32_t start_index; if (!Array::IndexFromObject(index, &start_index)) return Smi::FromInt(-1); uint32_t pattern_length = pat->length(); uint32_t sub_length = sub->length(); if (start_index + pattern_length > sub_length) { start_index = sub_length - pattern_length; } for (int i = start_index; i >= 0; i--) { bool found = true; for (uint32_t j = 0; j < pattern_length; j++) { if (sub->Get(i + j) != pat->Get(j)) { found = false; break; } } if (found) return Smi::FromInt(i); } return Smi::FromInt(-1);}static Object* Runtime_StringLocaleCompare(Arguments args) { NoHandleAllocation ha; ASSERT(args.length() == 2); CONVERT_CHECKED(String, str1, args[0]); CONVERT_CHECKED(String, str2, args[1]); if (str1 == str2) return Smi::FromInt(0); // Equal. int str1_length = str1->length(); int str2_length = str2->length(); // Decide trivial cases without flattening. if (str1_length == 0) { if (str2_length == 0) return Smi::FromInt(0); // Equal. return Smi::FromInt(-str2_length); } else { if (str2_length == 0) return Smi::FromInt(str1_length); } int end = str1_length < str2_length ? str1_length : str2_length; // No need to flatten if we are going to find the answer on the first // character. At this point we know there is at least one character // in each string, due to the trivial case handling above. int d = str1->Get(0) - str2->Get(0); if (d != 0) return Smi::FromInt(d); str1->TryFlatten(); str2->TryFlatten(); static StringInputBuffer buf1; static StringInputBuffer buf2; buf1.Reset(str1); buf2.Reset(str2); for (int i = 0; i < end; i++) { uint16_t char1 = buf1.GetNext(); uint16_t char2 = buf2.GetNext(); if (char1 != char2) return Smi::FromInt(char1 - char2); } return Smi::FromInt(str1_length - str2_length);}static Object* Runtime_StringSlice(Arguments args) { NoHandleAllocation ha; ASSERT(args.length() == 3); CONVERT_CHECKED(String, value, args[0]); CONVERT_DOUBLE_CHECKED(from_number, args[1]); CONVERT_DOUBLE_CHECKED(to_number, args[2]); int start = FastD2I(from_number); int end = FastD2I(to_number); RUNTIME_ASSERT(end >= start); RUNTIME_ASSERT(start >= 0); RUNTIME_ASSERT(end <= value->length()); return value->Slice(start, end);}static Object* Runtime_NumberToRadixString(Arguments args) { NoHandleAllocation ha; ASSERT(args.length() == 2); CONVERT_DOUBLE_CHECKED(value, args[0]); if (isnan(value)) { return Heap::AllocateStringFromAscii(CStrVector("NaN")); } if (isinf(value)) { if (value < 0) { return Heap::AllocateStringFromAscii(CStrVector("-Infinity")); } return Heap::AllocateStringFromAscii(CStrVector("Infinity")); } CONVERT_DOUBLE_CHECKED(radix_number, args[1]); int radix = FastD2I(radix_number); RUNTIME_ASSERT(2 <= radix && radix <= 36); char* str = DoubleToRadixCString(value, radix); Object* result = Heap::AllocateStringFromAscii(CStrVector(str)); DeleteArray(str); return result;}static Object* Runtime_NumberToFixed(Arguments args) { NoHandleAllocation ha; ASSERT(args.length() == 2); CONVERT_DOUBLE_CHECKED(value, args[0]); if (isnan(value)) { return Heap::AllocateStringFromAscii(CStrVector("NaN")); } if (isinf(value)) { if (value < 0) { return Heap::AllocateStringFromAscii(CStrVector("-Infinity")); } return Heap::AllocateStringFromAscii(CStrVector("Infinity")); } CONVERT_DOUBLE_CHECKED(f_number, args[1]); int f = FastD2I(f_number); RUNTIME_ASSERT(f >= 0); char* str = DoubleToFixedCString(value, f); Object* res = Heap::AllocateStringFromAscii(CStrVector(str)); DeleteArray(str); return res;}static Object* Runtime_NumberToExponential(Arguments args) { NoHandleAllocation ha; ASSERT(args.length() == 2); CONVERT_DOUBLE_CHECKED(value, args[0]); if (isnan(value)) { return Heap::AllocateStringFromAscii(CStrVector("NaN")); } if (isinf(value)) { if (value < 0) { return Heap::AllocateStringFromAscii(CStrVector("-Infinity")); } return Heap::AllocateStringFromAscii(CStrVector("Infinity")); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -