| 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
|
|
|