📄 execution.cc.svn-base
字号:
// --- C a l l s t o n a t i v e s ---#define RETURN_NATIVE_CALL(name, argc, argv, has_pending_exception) \ do { \ Object** args[argc] = argv; \ ASSERT(has_pending_exception != NULL); \ return Call(Top::name##_fun(), Top::builtins(), argc, args, \ has_pending_exception); \ } while (false)Handle<Object> Execution::ToBoolean(Handle<Object> obj) { // See the similar code in runtime.js:ToBoolean. if (obj->IsBoolean()) return obj; bool result = true; if (obj->IsString()) { result = Handle<String>::cast(obj)->length() != 0; } else if (obj->IsNull() || obj->IsUndefined()) { result = false; } else if (obj->IsNumber()) { double value = obj->Number(); result = !((value == 0) || isnan(value)); } return Handle<Object>(Heap::ToBoolean(result));}Handle<Object> Execution::ToNumber(Handle<Object> obj, bool* exc) { RETURN_NATIVE_CALL(to_number, 1, { obj.location() }, exc);}Handle<Object> Execution::ToString(Handle<Object> obj, bool* exc) { RETURN_NATIVE_CALL(to_string, 1, { obj.location() }, exc);}Handle<Object> Execution::ToDetailString(Handle<Object> obj, bool* exc) { RETURN_NATIVE_CALL(to_detail_string, 1, { obj.location() }, exc);}Handle<Object> Execution::ToObject(Handle<Object> obj, bool* exc) { if (obj->IsJSObject()) return obj; RETURN_NATIVE_CALL(to_object, 1, { obj.location() }, exc);}Handle<Object> Execution::ToInteger(Handle<Object> obj, bool* exc) { RETURN_NATIVE_CALL(to_integer, 1, { obj.location() }, exc);}Handle<Object> Execution::ToUint32(Handle<Object> obj, bool* exc) { RETURN_NATIVE_CALL(to_uint32, 1, { obj.location() }, exc);}Handle<Object> Execution::ToInt32(Handle<Object> obj, bool* exc) { RETURN_NATIVE_CALL(to_int32, 1, { obj.location() }, exc);}Handle<Object> Execution::NewDate(double time, bool* exc) { Handle<Object> time_obj = Factory::NewNumber(time); RETURN_NATIVE_CALL(create_date, 1, { time_obj.location() }, exc);}#undef RETURN_NATIVE_CALLHandle<Object> Execution::CharAt(Handle<String> string, uint32_t index) { int int_index = static_cast<int>(index); if (int_index < 0 || int_index >= string->length()) { return Factory::undefined_value(); } Handle<Object> char_at = GetProperty(Top::builtins(), Factory::char_at_symbol()); if (!char_at->IsJSFunction()) { return Factory::undefined_value(); } bool caught_exception; Handle<Object> index_object = Factory::NewNumberFromInt(int_index); Object** index_arg[] = { index_object.location() }; Handle<Object> result = TryCall(Handle<JSFunction>::cast(char_at), string, ARRAY_SIZE(index_arg), index_arg, &caught_exception); if (caught_exception) { return Factory::undefined_value(); } return result;}Handle<JSFunction> Execution::InstantiateFunction( Handle<FunctionTemplateInfo> data, bool* exc) { // Fast case: see if the function has already been instantiated int serial_number = Smi::cast(data->serial_number())->value(); Object* elm = Top::global_context()->function_cache()->GetElement(serial_number); if (!elm->IsUndefined()) return Handle<JSFunction>(JSFunction::cast(elm)); // The function has not yet been instantiated in this context; do it. Object** args[1] = { Handle<Object>::cast(data).location() }; Handle<Object> result = Call(Top::instantiate_fun(), Top::builtins(), 1, args, exc); if (*exc) return Handle<JSFunction>::null(); return Handle<JSFunction>::cast(result);}Handle<JSObject> Execution::InstantiateObject(Handle<ObjectTemplateInfo> data, bool* exc) { if (data->property_list()->IsUndefined() && !data->constructor()->IsUndefined()) { Object* result; { HandleScope scope; Handle<FunctionTemplateInfo> cons_template = Handle<FunctionTemplateInfo>( FunctionTemplateInfo::cast(data->constructor())); Handle<JSFunction> cons = InstantiateFunction(cons_template, exc); if (*exc) return Handle<JSObject>::null(); Handle<Object> value = New(cons, 0, NULL, exc); if (*exc) return Handle<JSObject>::null(); result = *value; } ASSERT(!*exc); return Handle<JSObject>(JSObject::cast(result)); } else { Object** args[1] = { Handle<Object>::cast(data).location() }; Handle<Object> result = Call(Top::instantiate_fun(), Top::builtins(), 1, args, exc); if (*exc) return Handle<JSObject>::null(); return Handle<JSObject>::cast(result); }}void Execution::ConfigureInstance(Handle<Object> instance, Handle<Object> instance_template, bool* exc) { Object** args[2] = { instance.location(), instance_template.location() }; Execution::Call(Top::configure_instance_fun(), Top::builtins(), 2, args, exc);}Handle<String> Execution::GetStackTraceLine(Handle<Object> recv, Handle<JSFunction> fun, Handle<Object> pos, Handle<Object> is_global) { const int argc = 4; Object** args[argc] = { recv.location(), Handle<Object>::cast(fun).location(), pos.location(), is_global.location() }; bool caught_exception = false; Handle<Object> result = TryCall(Top::get_stack_trace_line_fun(), Top::builtins(), argc, args, &caught_exception); if (caught_exception || !result->IsString()) return Factory::empty_symbol(); return Handle<String>::cast(result);}// --- P r i n t E x t e n s i o n ---const char* PrintExtension::kSource = "native function print();";v8::Handle<v8::FunctionTemplate> PrintExtension::GetNativeFunction( v8::Handle<v8::String> str) { return v8::FunctionTemplate::New(PrintExtension::Print);}v8::Handle<v8::Value> PrintExtension::Print(const v8::Arguments& args) { for (int i = 0; i < args.Length(); i++) { if (i != 0) printf(" "); v8::HandleScope scope; v8::Handle<v8::Value> arg = args[i]; v8::Handle<v8::String> string_obj = arg->ToString(); if (string_obj.IsEmpty()) return string_obj; int length = string_obj->Length(); uint16_t* string = NewArray<uint16_t>(length + 1); string_obj->Write(string); for (int j = 0; j < length; j++) printf("%lc", string[j]); DeleteArray(string); } printf("\n"); return v8::Undefined();}static PrintExtension kPrintExtension;v8::DeclareExtension kPrintExtensionDeclaration(&kPrintExtension);// --- L o a d E x t e n s i o n ---const char* LoadExtension::kSource = "native function load();";v8::Handle<v8::FunctionTemplate> LoadExtension::GetNativeFunction( v8::Handle<v8::String> str) { return v8::FunctionTemplate::New(LoadExtension::Load);}v8::Handle<v8::Value> LoadExtension::Load(const v8::Arguments& args) { v8::Handle<v8::String> path = args[0]->ToString(); // Create a handle for the result. Keep the result empty to be // useful as the return value in case of exceptions. v8::Handle<Value> result; if (path.IsEmpty()) return result; // Exception was thrown in ToString. // Check that the length of the file name is within bounds. static const int kMaxPathLength = 255; if (path->Length() > kMaxPathLength) { v8::Handle<v8::String> message = v8::String::New("Path name too long"); v8::ThrowException(v8::Exception::RangeError(message)); return result; } // Convert the JavaScript string path into a C string and read the // corresponding script from the file system. char path_buffer[kMaxPathLength + 1]; path->WriteAscii(path_buffer); bool exists; Vector<const char> script = ReadFile(path_buffer, &exists, false); // Find the base file name from the path. char* file_name_buffer = path_buffer; for (char* p = path_buffer; *p; p++) { if (*p == '/' || *p == '\\') file_name_buffer = p + 1; } // Throw an exception in case the script couldn't be read. if (script.is_empty()) { static const char* kErrorPrefix = "Unable to read from file "; static const size_t kErrorPrefixLength = 25; // strlen is not constant ASSERT(strlen(kErrorPrefix) == kErrorPrefixLength); static const int kMaxErrorLength = kMaxPathLength + kErrorPrefixLength; EmbeddedVector<char, kMaxErrorLength + 1> error_buffer; OS::SNPrintF(error_buffer, "%s%s", kErrorPrefix, file_name_buffer); v8::Handle<v8::String> error = v8::String::New(error_buffer.start(), error_buffer.length()); v8::ThrowException(v8::Exception::Error(error)); return result; } // Convert the file name buffer into a script origin v8::ScriptOrigin origin = v8::ScriptOrigin(v8::String::New(file_name_buffer)); // Compile and run script. v8::Handle<v8::String> source = v8::String::New(script.start(), script.length()); v8::Handle<v8::Script> code = v8::Script::Compile(source, &origin); // Run the code if no exception occurred during the compilation. In // case of syntax errors, the code is empty and the exception is // scheduled and will be thrown when returning to JavaScript. if (!code.IsEmpty()) result = code->Run(); script.Dispose(); return result;}static LoadExtension kLoadExtension;v8::DeclareExtension kLoadExtensionDeclaration(&kLoadExtension);// --- Q u i t E x t e n s i o n ---const char* QuitExtension::kSource = "native function quit();";v8::Handle<v8::FunctionTemplate> QuitExtension::GetNativeFunction( v8::Handle<v8::String> str) { return v8::FunctionTemplate::New(QuitExtension::Quit);}v8::Handle<v8::Value> QuitExtension::Quit(const v8::Arguments& args) { exit(args.Length() == 0 ? 0 : args[0]->Int32Value()); return v8::Undefined();}static QuitExtension kQuitExtension;v8::DeclareExtension kQuitExtensionDeclaration(&kQuitExtension);// --- V e r s i o n E x t e n s i o n ---static Extension kVersionExtension("v8/version", "function version(){ return 150; }");v8::DeclareExtension kVersionExtensionDeclaration(&kVersionExtension);// --- G C E x t e n s i o n ---const char* GCExtension::kSource = "native function gc();";v8::Handle<v8::FunctionTemplate> GCExtension::GetNativeFunction( v8::Handle<v8::String> str) { return v8::FunctionTemplate::New(GCExtension::GC);}v8::Handle<v8::Value> GCExtension::GC(const v8::Arguments& args) { // All allocation spaces other than NEW_SPACE have the same effect. Heap::CollectGarbage(0, OLD_DATA_SPACE); return v8::Undefined();}static GCExtension kGCExtension;v8::DeclareExtension kGCExtensionDeclaration(&kGCExtension);} } // namespace v8::internal
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -