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

Unified Diff: src/execution.cc

Issue 1360793002: [builtins] Refactor Invoke to deal with any kind of callable. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 3 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 side-by-side diff with in-line comments
Download patch
Index: src/execution.cc
diff --git a/src/execution.cc b/src/execution.cc
index c214e7c4e2f7e46bb28085a7f2976cd0aa73bcfa..9330de00bc643905c34403727d899898321f4cea 100644
--- a/src/execution.cc
+++ b/src/execution.cc
@@ -9,8 +9,6 @@
#include "src/deoptimizer.h"
#include "src/isolate-inl.h"
#include "src/messages.h"
-#include "src/parser.h"
-#include "src/prettyprinter.h"
#include "src/vm-state-inl.h"
namespace v8 {
@@ -55,47 +53,12 @@ static void PrintDeserializedCodeInfo(Handle<JSFunction> function) {
namespace {
-MUST_USE_RESULT MaybeHandle<Object> Invoke(bool is_construct,
- Handle<JSFunction> function,
+MUST_USE_RESULT MaybeHandle<Object> Invoke(Isolate* isolate, bool is_construct,
+ Handle<Object> target,
Handle<Object> receiver, int argc,
Handle<Object> args[],
Handle<Object> new_target) {
- Isolate* const isolate = function->GetIsolate();
-
- // Convert calls on global objects to be calls on the global
- // receiver instead to avoid having a 'this' pointer which refers
- // directly to a global object.
- if (receiver->IsGlobalObject()) {
- receiver =
- handle(Handle<GlobalObject>::cast(receiver)->global_proxy(), isolate);
- }
-
- // api callbacks can be called directly.
- if (!is_construct && function->shared()->IsApiFunction()) {
- SaveContext save(isolate);
- isolate->set_context(function->context());
- // Do proper receiver conversion for non-strict mode api functions.
- if (!receiver->IsJSReceiver() &&
- is_sloppy(function->shared()->language_mode())) {
- if (receiver->IsUndefined() || receiver->IsNull()) {
- receiver = handle(function->global_proxy(), isolate);
- } else {
- ASSIGN_RETURN_ON_EXCEPTION(
- isolate, receiver, Execution::ToObject(isolate, receiver), Object);
- }
- }
- DCHECK(function->context()->global_object()->IsGlobalObject());
- auto value = Builtins::InvokeApiFunction(function, receiver, argc, args);
- bool has_exception = value.is_null();
- DCHECK(has_exception == isolate->has_pending_exception());
- if (has_exception) {
- isolate->ReportPendingMessages();
- return MaybeHandle<Object>();
- } else {
- isolate->clear_pending_message();
- }
- return value;
- }
+ DCHECK(!receiver->IsGlobalObject());
// Entering JavaScript.
VMState<JS> state(isolate);
@@ -109,7 +72,7 @@ MUST_USE_RESULT MaybeHandle<Object> Invoke(bool is_construct,
// Placeholder for return value.
Object* value = NULL;
- typedef Object* (*JSEntryFunction)(Object* new_target, Object* function,
+ typedef Object* (*JSEntryFunction)(Object* new_target, Object* target,
Object* receiver, int argc,
Object*** args);
@@ -117,10 +80,6 @@ MUST_USE_RESULT MaybeHandle<Object> Invoke(bool is_construct,
? isolate->factory()->js_construct_entry_code()
: isolate->factory()->js_entry_code();
- // Make sure that the global object of the context we're about to
- // make the current one is indeed a global object.
- DCHECK(function->context()->global_object()->IsGlobalObject());
-
{
// Save and restore context around invocation and block the
// allocation of handles without explicit handle scopes.
@@ -130,10 +89,12 @@ MUST_USE_RESULT MaybeHandle<Object> Invoke(bool is_construct,
// Call the function through the right JS entry stub.
Object* orig_func = *new_target;
- JSFunction* func = *function;
+ Object* func = *target;
Object* recv = *receiver;
Object*** argv = reinterpret_cast<Object***>(args);
- if (FLAG_profile_deserialization) PrintDeserializedCodeInfo(function);
+ if (FLAG_profile_deserialization && target->IsJSFunction()) {
+ PrintDeserializedCodeInfo(Handle<JSFunction>::cast(target));
+ }
value = CALL_GENERATED_CODE(stub_entry, orig_func, func, recv, argc, argv);
}
@@ -163,30 +124,64 @@ MUST_USE_RESULT MaybeHandle<Object> Invoke(bool is_construct,
} // namespace
+// static
MaybeHandle<Object> Execution::Call(Isolate* isolate, Handle<Object> callable,
Handle<Object> receiver, int argc,
Handle<Object> argv[]) {
- if (!callable->IsJSFunction()) {
- ASSIGN_RETURN_ON_EXCEPTION(isolate, callable,
- GetFunctionDelegate(isolate, callable), Object);
+ // Convert calls on global objects to be calls on the global
+ // receiver instead to avoid having a 'this' pointer which refers
+ // directly to a global object.
+ if (receiver->IsGlobalObject()) {
+ receiver =
+ handle(Handle<GlobalObject>::cast(receiver)->global_proxy(), isolate);
+ }
+
+ // api callbacks can be called directly.
+ if (callable->IsJSFunction() &&
+ Handle<JSFunction>::cast(callable)->shared()->IsApiFunction()) {
+ Handle<JSFunction> function = Handle<JSFunction>::cast(callable);
+ SaveContext save(isolate);
+ isolate->set_context(function->context());
+ // Do proper receiver conversion for non-strict mode api functions.
+ if (!receiver->IsJSReceiver() &&
+ is_sloppy(function->shared()->language_mode())) {
+ if (receiver->IsUndefined() || receiver->IsNull()) {
+ receiver = handle(function->global_proxy(), isolate);
+ } else {
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, receiver, Execution::ToObject(isolate, receiver), Object);
+ }
+ }
+ DCHECK(function->context()->global_object()->IsGlobalObject());
+ auto value = Builtins::InvokeApiFunction(function, receiver, argc, argv);
+ bool has_exception = value.is_null();
+ DCHECK(has_exception == isolate->has_pending_exception());
+ if (has_exception) {
+ isolate->ReportPendingMessages();
+ return MaybeHandle<Object>();
+ } else {
+ isolate->clear_pending_message();
+ }
+ return value;
}
- Handle<JSFunction> func = Handle<JSFunction>::cast(callable);
- return Invoke(false, func, receiver, argc, argv,
+ return Invoke(isolate, false, callable, receiver, argc, argv,
isolate->factory()->undefined_value());
}
+// static
MaybeHandle<Object> Execution::New(Handle<JSFunction> constructor, int argc,
Handle<Object> argv[]) {
- return New(constructor, constructor, argc, argv);
+ return New(constructor->GetIsolate(), constructor, constructor, argc, argv);
}
-MaybeHandle<Object> Execution::New(Handle<JSFunction> constructor,
- Handle<JSFunction> new_target, int argc,
+// static
+MaybeHandle<Object> Execution::New(Isolate* isolate, Handle<Object> constructor,
+ Handle<Object> new_target, int argc,
Handle<Object> argv[]) {
- return Invoke(true, constructor, handle(constructor->global_proxy()), argc,
- argv, new_target);
+ return Invoke(isolate, true, constructor,
+ isolate->factory()->undefined_value(), argc, argv, new_target);
}
@@ -234,98 +229,6 @@ MaybeHandle<Object> Execution::TryCall(Handle<JSFunction> func,
}
-// static
-MaybeHandle<JSFunction> Execution::GetFunctionDelegate(Isolate* isolate,
- Handle<Object> object) {
- DCHECK(!object->IsJSFunction());
- if (object->IsHeapObject()) {
- DisallowHeapAllocation no_gc;
-
- // If object is a function proxy, get its handler. Iterate if necessary.
- Object* fun = *object;
- while (fun->IsJSFunctionProxy()) {
- fun = JSFunctionProxy::cast(fun)->call_trap();
- }
- if (fun->IsJSFunction()) {
- return handle(JSFunction::cast(fun), isolate);
- }
-
- // We can also have exotic objects with [[Call]] internal methods.
- if (fun->IsCallable()) {
- return handle(isolate->native_context()->call_as_function_delegate(),
- isolate);
- }
- }
-
- // If the Object doesn't have an instance-call handler we should
- // throw a non-callable exception.
- Handle<String> callsite = RenderCallSite(isolate, object);
- THROW_NEW_ERROR(isolate,
- NewTypeError(MessageTemplate::kCalledNonCallable, callsite),
- JSFunction);
-}
-
-
-// static
-MaybeHandle<JSFunction> Execution::GetConstructorDelegate(
- Isolate* isolate, Handle<Object> object) {
- // If you return a function from here, it will be called when an
- // attempt is made to call the given object as a constructor.
-
- DCHECK(!object->IsJSFunction());
- if (object->IsHeapObject()) {
- DisallowHeapAllocation no_gc;
-
- // If object is a function proxies, get its handler. Iterate if necessary.
- Object* fun = *object;
- while (fun->IsJSFunctionProxy()) {
- // TODO(bmeurer): This should work based on [[Construct]]; our proxies
- // are screwed.
- fun = JSFunctionProxy::cast(fun)->call_trap();
- }
- if (fun->IsJSFunction()) {
- return handle(JSFunction::cast(fun), isolate);
- }
-
- // We can also have exotic objects with [[Construct]] internal methods.
- // TODO(bmeurer): This should use IsConstructor() as dictacted by the spec.
- if (fun->IsCallable()) {
- return handle(isolate->native_context()->call_as_constructor_delegate(),
- isolate);
- }
- }
-
- // If the Object doesn't have an instance-call handler we should
- // throw a non-callable exception.
- Handle<String> callsite = RenderCallSite(isolate, object);
- THROW_NEW_ERROR(isolate,
- NewTypeError(MessageTemplate::kCalledNonCallable, callsite),
- JSFunction);
-}
-
-
-// static
-Handle<String> Execution::RenderCallSite(Isolate* isolate,
- Handle<Object> object) {
- MessageLocation location;
- if (isolate->ComputeLocation(&location)) {
- Zone zone;
- base::SmartPointer<ParseInfo> info(
- location.function()->shared()->is_function()
- ? new ParseInfo(&zone, location.function())
- : new ParseInfo(&zone, location.script()));
- if (Parser::ParseStatic(info.get())) {
- CallPrinter printer(isolate, &zone);
- const char* string = printer.Print(info->literal(), location.start_pos());
- return isolate->factory()->NewStringFromAsciiChecked(string);
- } else {
- isolate->clear_pending_exception();
- }
- }
- return Object::TypeOf(isolate, object);
-}
-
-
void StackGuard::SetStackLimit(uintptr_t limit) {
ExecutionAccess access(isolate_);
// If the current limits are special (e.g. due to a pending interrupt) then
« src/arm/builtins-arm.cc ('K') | « src/execution.h ('k') | src/ia32/builtins-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698