Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(215)

Side by Side Diff: src/builtins.cc

Issue 2092943003: Pass in the original receiver to avoid use-after-return issues (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/builtins.h" 5 #include "src/builtins.h"
6 6
7 #include "src/api-arguments.h" 7 #include "src/api-arguments.h"
8 #include "src/api-natives.h" 8 #include "src/api-natives.h"
9 #include "src/api.h" 9 #include "src/api.h"
10 #include "src/base/ieee754.h" 10 #include "src/base/ieee754.h"
(...skipping 5130 matching lines...) Expand 10 before | Expand all | Expand 10 after
5141 JSObject* current = iter.GetCurrent<JSObject>(); 5141 JSObject* current = iter.GetCurrent<JSObject>();
5142 if (signature->IsTemplateFor(current)) return current; 5142 if (signature->IsTemplateFor(current)) return current;
5143 } 5143 }
5144 return nullptr; 5144 return nullptr;
5145 } 5145 }
5146 5146
5147 template <bool is_construct> 5147 template <bool is_construct>
5148 MUST_USE_RESULT MaybeHandle<Object> HandleApiCallHelper( 5148 MUST_USE_RESULT MaybeHandle<Object> HandleApiCallHelper(
5149 Isolate* isolate, Handle<HeapObject> function, 5149 Isolate* isolate, Handle<HeapObject> function,
5150 Handle<HeapObject> new_target, Handle<FunctionTemplateInfo> fun_data, 5150 Handle<HeapObject> new_target, Handle<FunctionTemplateInfo> fun_data,
5151 BuiltinArguments args) { 5151 Handle<Object> receiver, BuiltinArguments args) {
5152 Handle<JSObject> receiver; 5152 Handle<JSObject> js_receiver;
5153 JSObject* raw_holder; 5153 JSObject* raw_holder;
5154 if (is_construct) { 5154 if (is_construct) {
5155 DCHECK(args.receiver()->IsTheHole(isolate)); 5155 DCHECK(args.receiver()->IsTheHole(isolate));
5156 if (fun_data->instance_template()->IsUndefined(isolate)) { 5156 if (fun_data->instance_template()->IsUndefined(isolate)) {
5157 v8::Local<ObjectTemplate> templ = 5157 v8::Local<ObjectTemplate> templ =
5158 ObjectTemplate::New(reinterpret_cast<v8::Isolate*>(isolate), 5158 ObjectTemplate::New(reinterpret_cast<v8::Isolate*>(isolate),
5159 ToApiHandle<v8::FunctionTemplate>(fun_data)); 5159 ToApiHandle<v8::FunctionTemplate>(fun_data));
5160 fun_data->set_instance_template(*Utils::OpenHandle(*templ)); 5160 fun_data->set_instance_template(*Utils::OpenHandle(*templ));
5161 } 5161 }
5162 Handle<ObjectTemplateInfo> instance_template( 5162 Handle<ObjectTemplateInfo> instance_template(
5163 ObjectTemplateInfo::cast(fun_data->instance_template()), isolate); 5163 ObjectTemplateInfo::cast(fun_data->instance_template()), isolate);
5164 ASSIGN_RETURN_ON_EXCEPTION( 5164 ASSIGN_RETURN_ON_EXCEPTION(
5165 isolate, receiver, 5165 isolate, js_receiver,
5166 ApiNatives::InstantiateObject(instance_template, 5166 ApiNatives::InstantiateObject(instance_template,
5167 Handle<JSReceiver>::cast(new_target)), 5167 Handle<JSReceiver>::cast(new_target)),
5168 Object); 5168 Object);
5169 args[0] = *receiver; 5169 args[0] = *js_receiver;
5170 DCHECK_EQ(*receiver, *args.receiver()); 5170 DCHECK_EQ(*js_receiver, *args.receiver());
5171 5171
5172 raw_holder = *receiver; 5172 raw_holder = *js_receiver;
5173 } else { 5173 } else {
5174 DCHECK(args.receiver()->IsJSReceiver()); 5174 DCHECK(receiver->IsJSReceiver());
5175 5175
5176 Handle<JSReceiver> object = args.at<JSReceiver>(0); 5176 if (!receiver->IsJSObject()) {
5177 if (!object->IsJSObject()) {
5178 // This function cannot be called with the given receiver. Abort! 5177 // This function cannot be called with the given receiver. Abort!
5179 THROW_NEW_ERROR( 5178 THROW_NEW_ERROR(
5180 isolate, NewTypeError(MessageTemplate::kIllegalInvocation), Object); 5179 isolate, NewTypeError(MessageTemplate::kIllegalInvocation), Object);
5181 } 5180 }
5182 5181
5183 receiver = Handle<JSObject>::cast(object); 5182 js_receiver = Handle<JSObject>::cast(receiver);
5184 5183
5185 if (!fun_data->accept_any_receiver() && receiver->IsAccessCheckNeeded() && 5184 if (!fun_data->accept_any_receiver() &&
5186 !isolate->MayAccess(handle(isolate->context()), receiver)) { 5185 js_receiver->IsAccessCheckNeeded() &&
5187 isolate->ReportFailedAccessCheck(receiver); 5186 !isolate->MayAccess(handle(isolate->context()), js_receiver)) {
5187 isolate->ReportFailedAccessCheck(js_receiver);
5188 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); 5188 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
5189 } 5189 }
5190 5190
5191 raw_holder = GetCompatibleReceiver(isolate, *fun_data, *receiver); 5191 raw_holder = GetCompatibleReceiver(isolate, *fun_data, *js_receiver);
5192 5192
5193 if (raw_holder == nullptr) { 5193 if (raw_holder == nullptr) {
5194 // This function cannot be called with the given receiver. Abort! 5194 // This function cannot be called with the given receiver. Abort!
5195 THROW_NEW_ERROR( 5195 THROW_NEW_ERROR(
5196 isolate, NewTypeError(MessageTemplate::kIllegalInvocation), Object); 5196 isolate, NewTypeError(MessageTemplate::kIllegalInvocation), Object);
5197 } 5197 }
5198 } 5198 }
5199 5199
5200 Object* raw_call_data = fun_data->call_code(); 5200 Object* raw_call_data = fun_data->call_code();
5201 if (!raw_call_data->IsUndefined(isolate)) { 5201 if (!raw_call_data->IsUndefined(isolate)) {
5202 DCHECK(raw_call_data->IsCallHandlerInfo()); 5202 DCHECK(raw_call_data->IsCallHandlerInfo());
5203 CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data); 5203 CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data);
5204 Object* callback_obj = call_data->callback(); 5204 Object* callback_obj = call_data->callback();
5205 v8::FunctionCallback callback = 5205 v8::FunctionCallback callback =
5206 v8::ToCData<v8::FunctionCallback>(callback_obj); 5206 v8::ToCData<v8::FunctionCallback>(callback_obj);
5207 Object* data_obj = call_data->data(); 5207 Object* data_obj = call_data->data();
5208 5208
5209 LOG(isolate, ApiObjectAccess("call", JSObject::cast(*args.receiver()))); 5209 LOG(isolate, ApiObjectAccess("call", JSObject::cast(*js_receiver)));
5210 5210
5211 FunctionCallbackArguments custom(isolate, data_obj, *function, raw_holder, 5211 FunctionCallbackArguments custom(isolate, data_obj, *function, raw_holder,
5212 *new_target, &args[0] - 1, 5212 *new_target, &args[0] - 1,
5213 args.length() - 1); 5213 args.length() - 1);
5214 5214
5215 Handle<Object> result = custom.Call(callback); 5215 Handle<Object> result = custom.Call(callback);
5216 5216
5217 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); 5217 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
5218 if (result.is_null()) { 5218 if (result.is_null()) {
5219 if (is_construct) return receiver; 5219 if (is_construct) return js_receiver;
5220 return isolate->factory()->undefined_value(); 5220 return isolate->factory()->undefined_value();
5221 } 5221 }
5222 // Rebox the result. 5222 // Rebox the result.
5223 result->VerifyApiCallResultType(); 5223 result->VerifyApiCallResultType();
5224 if (!is_construct || result->IsJSObject()) return handle(*result, isolate); 5224 if (!is_construct || result->IsJSObject()) return handle(*result, isolate);
5225 } 5225 }
5226 5226
5227 return receiver; 5227 return js_receiver;
5228 } 5228 }
5229 5229
5230 } // namespace 5230 } // namespace
5231 5231
5232 5232
5233 BUILTIN(HandleApiCall) { 5233 BUILTIN(HandleApiCall) {
5234 HandleScope scope(isolate); 5234 HandleScope scope(isolate);
5235 Handle<JSFunction> function = args.target<JSFunction>(); 5235 Handle<JSFunction> function = args.target<JSFunction>();
5236 Handle<Object> receiver = args.receiver();
5236 Handle<HeapObject> new_target = args.new_target(); 5237 Handle<HeapObject> new_target = args.new_target();
5237 Handle<FunctionTemplateInfo> fun_data(function->shared()->get_api_func_data(), 5238 Handle<FunctionTemplateInfo> fun_data(function->shared()->get_api_func_data(),
5238 isolate); 5239 isolate);
5239 if (new_target->IsJSReceiver()) { 5240 if (new_target->IsJSReceiver()) {
5240 RETURN_RESULT_OR_FAILURE( 5241 RETURN_RESULT_OR_FAILURE(
5241 isolate, HandleApiCallHelper<true>(isolate, function, new_target, 5242 isolate, HandleApiCallHelper<true>(isolate, function, new_target,
5242 fun_data, args)); 5243 fun_data, receiver, args));
5243 } else { 5244 } else {
5244 RETURN_RESULT_OR_FAILURE( 5245 RETURN_RESULT_OR_FAILURE(
5245 isolate, HandleApiCallHelper<false>(isolate, function, new_target, 5246 isolate, HandleApiCallHelper<false>(isolate, function, new_target,
5246 fun_data, args)); 5247 fun_data, receiver, args));
5247 } 5248 }
5248 } 5249 }
5249 5250
5250 5251
5251 Handle<Code> Builtins::CallFunction(ConvertReceiverMode mode, 5252 Handle<Code> Builtins::CallFunction(ConvertReceiverMode mode,
5252 TailCallMode tail_call_mode) { 5253 TailCallMode tail_call_mode) {
5253 switch (tail_call_mode) { 5254 switch (tail_call_mode) {
5254 case TailCallMode::kDisallow: 5255 case TailCallMode::kDisallow:
5255 switch (mode) { 5256 switch (mode) {
5256 case ConvertReceiverMode::kNullOrUndefined: 5257 case ConvertReceiverMode::kNullOrUndefined:
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
5382 argv[argc + 2] = *receiver; 5383 argv[argc + 2] = *receiver;
5383 for (int i = 0; i < argc; ++i) { 5384 for (int i = 0; i < argc; ++i) {
5384 argv[argc - i + 1] = *args[i]; 5385 argv[argc - i + 1] = *args[i];
5385 } 5386 }
5386 argv[1] = *function; 5387 argv[1] = *function;
5387 argv[0] = *new_target; 5388 argv[0] = *new_target;
5388 MaybeHandle<Object> result; 5389 MaybeHandle<Object> result;
5389 { 5390 {
5390 RelocatableArguments arguments(isolate, argc + 3, &argv[argc] + 2); 5391 RelocatableArguments arguments(isolate, argc + 3, &argv[argc] + 2);
5391 result = HandleApiCallHelper<false>(isolate, function, new_target, fun_data, 5392 result = HandleApiCallHelper<false>(isolate, function, new_target, fun_data,
5392 arguments); 5393 receiver, arguments);
5393 } 5394 }
5394 if (argv != small_argv) delete[] argv; 5395 if (argv != small_argv) delete[] argv;
5395 return result; 5396 return result;
5396 } 5397 }
5397 5398
5398 5399
5399 // Helper function to handle calls to non-function objects created through the 5400 // Helper function to handle calls to non-function objects created through the
5400 // API. The object can be called as either a constructor (using new) or just as 5401 // API. The object can be called as either a constructor (using new) or just as
5401 // a function (without new). 5402 // a function (without new).
5402 MUST_USE_RESULT static Object* HandleApiCallAsFunctionOrConstructor( 5403 MUST_USE_RESULT static Object* HandleApiCallAsFunctionOrConstructor(
(...skipping 737 matching lines...) Expand 10 before | Expand all | Expand 10 after
6140 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) 6141 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H)
6141 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) 6142 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A)
6142 #undef DEFINE_BUILTIN_ACCESSOR_C 6143 #undef DEFINE_BUILTIN_ACCESSOR_C
6143 #undef DEFINE_BUILTIN_ACCESSOR_A 6144 #undef DEFINE_BUILTIN_ACCESSOR_A
6144 #undef DEFINE_BUILTIN_ACCESSOR_T 6145 #undef DEFINE_BUILTIN_ACCESSOR_T
6145 #undef DEFINE_BUILTIN_ACCESSOR_S 6146 #undef DEFINE_BUILTIN_ACCESSOR_S
6146 #undef DEFINE_BUILTIN_ACCESSOR_H 6147 #undef DEFINE_BUILTIN_ACCESSOR_H
6147 6148
6148 } // namespace internal 6149 } // namespace internal
6149 } // namespace v8 6150 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698