| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 21921 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 21932 if (setter_i.is_null()) setter_i = isolate->factory()->null_value(); | 21932 if (setter_i.is_null()) setter_i = isolate->factory()->null_value(); |
| 21933 i::JSObject::DefineAccessor(v8::Utils::OpenHandle(*object), | 21933 i::JSObject::DefineAccessor(v8::Utils::OpenHandle(*object), |
| 21934 v8::Utils::OpenHandle(*name), | 21934 v8::Utils::OpenHandle(*name), |
| 21935 getter_i, | 21935 getter_i, |
| 21936 setter_i, | 21936 setter_i, |
| 21937 static_cast<PropertyAttributes>(attribute), | 21937 static_cast<PropertyAttributes>(attribute), |
| 21938 settings); | 21938 settings); |
| 21939 } | 21939 } |
| 21940 | 21940 |
| 21941 public: | 21941 public: |
| 21942 void Run(bool use_signature, bool global) { | 21942 enum SignatureType { |
| 21943 kNoSignature, |
| 21944 kSignatureOnReceiver, |
| 21945 kSignatureOnPrototype |
| 21946 }; |
| 21947 |
| 21948 void RunAll() { |
| 21949 SignatureType signature_types[] = |
| 21950 {kNoSignature, kSignatureOnReceiver, kSignatureOnPrototype}; |
| 21951 for (unsigned i = 0; i < ARRAY_SIZE(signature_types); i++) { |
| 21952 SignatureType signature_type = signature_types[i]; |
| 21953 for (int j = 0; j < 2; j++) { |
| 21954 bool global = j == 0; |
| 21955 int key = signature_type + |
| 21956 ARRAY_SIZE(signature_types) * (global ? 1 : 0); |
| 21957 Run(signature_type, global, key); |
| 21958 } |
| 21959 } |
| 21960 } |
| 21961 |
| 21962 void Run(SignatureType signature_type, bool global, int key) { |
| 21943 v8::Isolate* isolate = CcTest::isolate(); | 21963 v8::Isolate* isolate = CcTest::isolate(); |
| 21944 v8::HandleScope scope(isolate); | 21964 v8::HandleScope scope(isolate); |
| 21945 // Build a template for signature checks. | 21965 // Build a template for signature checks. |
| 21946 Local<v8::ObjectTemplate> signature_template; | 21966 Local<v8::ObjectTemplate> signature_template; |
| 21947 Local<v8::Signature> signature; | 21967 Local<v8::Signature> signature; |
| 21948 { | 21968 { |
| 21949 Local<v8::FunctionTemplate> parent_template = | 21969 Local<v8::FunctionTemplate> parent_template = |
| 21950 FunctionTemplate::New(isolate); | 21970 FunctionTemplate::New(isolate); |
| 21951 parent_template->SetHiddenPrototype(true); | 21971 parent_template->SetHiddenPrototype(true); |
| 21952 Local<v8::FunctionTemplate> function_template | 21972 Local<v8::FunctionTemplate> function_template |
| 21953 = FunctionTemplate::New(isolate); | 21973 = FunctionTemplate::New(isolate); |
| 21954 function_template->Inherit(parent_template); | 21974 function_template->Inherit(parent_template); |
| 21955 if (use_signature) { | 21975 switch (signature_type) { |
| 21956 signature = v8::Signature::New(isolate, parent_template); | 21976 case kNoSignature: |
| 21977 break; |
| 21978 case kSignatureOnReceiver: |
| 21979 signature = v8::Signature::New(isolate, function_template); |
| 21980 break; |
| 21981 case kSignatureOnPrototype: |
| 21982 signature = v8::Signature::New(isolate, parent_template); |
| 21983 break; |
| 21957 } | 21984 } |
| 21958 signature_template = function_template->InstanceTemplate(); | 21985 signature_template = function_template->InstanceTemplate(); |
| 21959 } | 21986 } |
| 21960 // Global object must pass checks. | 21987 // Global object must pass checks. |
| 21961 Local<v8::Context> context = | 21988 Local<v8::Context> context = |
| 21962 v8::Context::New(isolate, NULL, signature_template); | 21989 v8::Context::New(isolate, NULL, signature_template); |
| 21963 v8::Context::Scope context_scope(context); | 21990 v8::Context::Scope context_scope(context); |
| 21964 // Install regular object that can pass signature checks. | 21991 // Install regular object that can pass signature checks. |
| 21965 Local<Object> function_receiver = signature_template->NewInstance(); | 21992 Local<Object> function_receiver = signature_template->NewInstance(); |
| 21966 context->Global()->Set(v8_str("function_receiver"), function_receiver); | 21993 context->Global()->Set(v8_str("function_receiver"), function_receiver); |
| 21967 // Get the holder objects. | 21994 // Get the holder objects. |
| 21968 Local<Object> inner_global = | 21995 Local<Object> inner_global = |
| 21969 Local<Object>::Cast(context->Global()->GetPrototype()); | 21996 Local<Object>::Cast(context->Global()->GetPrototype()); |
| 21970 Local<Object> function_holder = | 21997 // Install functions on hidden prototype object if there is one. |
| 21971 Local<Object>::Cast(function_receiver->GetPrototype()); | |
| 21972 // Install function on hidden prototype object. | |
| 21973 data = Object::New(isolate); | 21998 data = Object::New(isolate); |
| 21974 Local<FunctionTemplate> function_template = FunctionTemplate::New( | 21999 Local<FunctionTemplate> function_template = FunctionTemplate::New( |
| 21975 isolate, OptimizationCallback, data, signature); | 22000 isolate, OptimizationCallback, data, signature); |
| 21976 Local<Function> function = function_template->GetFunction(); | 22001 Local<Function> function = function_template->GetFunction(); |
| 21977 Local<Object> global_holder = Local<Object>::Cast( | 22002 Local<Object> global_holder = inner_global; |
| 21978 inner_global->GetPrototype()); | 22003 Local<Object> function_holder = function_receiver; |
| 22004 if (signature_type == kSignatureOnPrototype) { |
| 22005 function_holder = Local<Object>::Cast(function_holder->GetPrototype()); |
| 22006 global_holder = Local<Object>::Cast(global_holder->GetPrototype()); |
| 22007 } |
| 21979 global_holder->Set(v8_str("g_f"), function); | 22008 global_holder->Set(v8_str("g_f"), function); |
| 21980 SetAccessorProperty(global_holder, v8_str("g_acc"), function, function); | 22009 SetAccessorProperty(global_holder, v8_str("g_acc"), function, function); |
| 21981 function_holder->Set(v8_str("f"), function); | 22010 function_holder->Set(v8_str("f"), function); |
| 21982 SetAccessorProperty(function_holder, v8_str("acc"), function, function); | 22011 SetAccessorProperty(function_holder, v8_str("acc"), function, function); |
| 21983 // Initialize expected values. | 22012 // Initialize expected values. |
| 21984 callee = function; | 22013 callee = function; |
| 21985 count = 0; | 22014 count = 0; |
| 21986 if (global) { | 22015 if (global) { |
| 21987 receiver = context->Global(); | 22016 receiver = context->Global(); |
| 21988 holder = inner_global; | 22017 holder = inner_global; |
| 21989 } else { | 22018 } else { |
| 21990 holder = function_receiver; | 22019 holder = function_receiver; |
| 21991 // If not using a signature, add something else to the prototype chain | 22020 // If not using a signature, add something else to the prototype chain |
| 21992 // to test the case that holder != receiver | 22021 // to test the case that holder != receiver |
| 21993 if (!use_signature) { | 22022 if (signature_type == kNoSignature) { |
| 21994 receiver = Local<Object>::Cast(CompileRun( | 22023 receiver = Local<Object>::Cast(CompileRun( |
| 21995 "var receiver_subclass = {};\n" | 22024 "var receiver_subclass = {};\n" |
| 21996 "receiver_subclass.__proto__ = function_receiver;\n" | 22025 "receiver_subclass.__proto__ = function_receiver;\n" |
| 21997 "receiver_subclass")); | 22026 "receiver_subclass")); |
| 21998 } else { | 22027 } else { |
| 21999 receiver = Local<Object>::Cast(CompileRun( | 22028 receiver = Local<Object>::Cast(CompileRun( |
| 22000 "var receiver_subclass = function_receiver;\n" | 22029 "var receiver_subclass = function_receiver;\n" |
| 22001 "receiver_subclass")); | 22030 "receiver_subclass")); |
| 22002 } | 22031 } |
| 22003 } | 22032 } |
| 22004 // With no signature, the holder is not set. | 22033 // With no signature, the holder is not set. |
| 22005 if (!use_signature) holder = receiver; | 22034 if (signature_type == kNoSignature) holder = receiver; |
| 22006 // build wrap_function | 22035 // build wrap_function |
| 22007 int key = (use_signature ? 1 : 0) + 2 * (global ? 1 : 0); | |
| 22008 i::ScopedVector<char> wrap_function(200); | 22036 i::ScopedVector<char> wrap_function(200); |
| 22009 if (global) { | 22037 if (global) { |
| 22010 i::OS::SNPrintF( | 22038 i::OS::SNPrintF( |
| 22011 wrap_function, | 22039 wrap_function, |
| 22012 "function wrap_f_%d() { var f = g_f; return f(); }\n" | 22040 "function wrap_f_%d() { var f = g_f; return f(); }\n" |
| 22013 "function wrap_get_%d() { return this.g_acc; }\n" | 22041 "function wrap_get_%d() { return this.g_acc; }\n" |
| 22014 "function wrap_set_%d() { this.g_acc = 1; }\n", | 22042 "function wrap_set_%d() { this.g_acc = 1; }\n", |
| 22015 key, key, key); | 22043 key, key, key); |
| 22016 } else { | 22044 } else { |
| 22017 i::OS::SNPrintF( | 22045 i::OS::SNPrintF( |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 22056 Local<Object> ApiCallOptimizationChecker::data; | 22084 Local<Object> ApiCallOptimizationChecker::data; |
| 22057 Local<Object> ApiCallOptimizationChecker::receiver; | 22085 Local<Object> ApiCallOptimizationChecker::receiver; |
| 22058 Local<Object> ApiCallOptimizationChecker::holder; | 22086 Local<Object> ApiCallOptimizationChecker::holder; |
| 22059 Local<Object> ApiCallOptimizationChecker::callee; | 22087 Local<Object> ApiCallOptimizationChecker::callee; |
| 22060 int ApiCallOptimizationChecker::count = 0; | 22088 int ApiCallOptimizationChecker::count = 0; |
| 22061 | 22089 |
| 22062 | 22090 |
| 22063 TEST(TestFunctionCallOptimization) { | 22091 TEST(TestFunctionCallOptimization) { |
| 22064 i::FLAG_allow_natives_syntax = true; | 22092 i::FLAG_allow_natives_syntax = true; |
| 22065 ApiCallOptimizationChecker checker; | 22093 ApiCallOptimizationChecker checker; |
| 22066 checker.Run(true, true); | 22094 checker.RunAll(); |
| 22067 checker.Run(false, true); | |
| 22068 checker.Run(true, false); | |
| 22069 checker.Run(false, false); | |
| 22070 } | 22095 } |
| OLD | NEW |