aboutsummaryrefslogtreecommitdiff
path: root/deps/v8/src/runtime/runtime-function.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/runtime/runtime-function.cc')
-rw-r--r--deps/v8/src/runtime/runtime-function.cc328
1 files changed, 36 insertions, 292 deletions
diff --git a/deps/v8/src/runtime/runtime-function.cc b/deps/v8/src/runtime/runtime-function.cc
index 16e6149e7c..befd337098 100644
--- a/deps/v8/src/runtime/runtime-function.cc
+++ b/deps/v8/src/runtime/runtime-function.cc
@@ -7,7 +7,6 @@
#include "src/accessors.h"
#include "src/arguments.h"
#include "src/compiler.h"
-#include "src/deoptimizer.h"
#include "src/frames-inl.h"
#include "src/isolate-inl.h"
#include "src/messages.h"
@@ -38,74 +37,14 @@ RUNTIME_FUNCTION(Runtime_FunctionSetName) {
}
-RUNTIME_FUNCTION(Runtime_FunctionNameShouldPrintAsAnonymous) {
- SealHandleScope shs(isolate);
- DCHECK(args.length() == 1);
- CONVERT_ARG_CHECKED(JSFunction, f, 0);
- return isolate->heap()->ToBoolean(
- f->shared()->name_should_print_as_anonymous());
-}
-
-
-RUNTIME_FUNCTION(Runtime_CompleteFunctionConstruction) {
- SealHandleScope shs(isolate);
- DCHECK(args.length() == 3);
- CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0);
- CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, 1);
- CONVERT_ARG_HANDLE_CHECKED(Object, new_target, 2);
- func->shared()->set_name_should_print_as_anonymous(true);
-
- // If new.target is equal to |constructor| then the function |func| created
- // is already correctly setup and nothing else should be done here.
- // But if new.target is not equal to |constructor| then we are have a
- // Function builtin subclassing case and therefore the function |func|
- // has wrong initial map. To fix that we create a new function object with
- // correct initial map.
- if (new_target->IsUndefined() || *constructor == *new_target) {
- return *func;
- }
-
- // Create a new JSFunction object with correct initial map.
- HandleScope handle_scope(isolate);
- Handle<JSFunction> original_constructor =
- Handle<JSFunction>::cast(new_target);
-
- DCHECK(constructor->has_initial_map());
- Handle<Map> initial_map =
- JSFunction::EnsureDerivedHasInitialMap(original_constructor, constructor);
-
- Handle<SharedFunctionInfo> shared_info(func->shared(), isolate);
- Handle<Context> context(func->context(), isolate);
- Handle<JSFunction> result =
- isolate->factory()->NewFunctionFromSharedFunctionInfo(
- initial_map, shared_info, context, NOT_TENURED);
- DCHECK_EQ(func->IsConstructor(), result->IsConstructor());
- return *result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_FunctionIsArrow) {
- SealHandleScope shs(isolate);
- DCHECK(args.length() == 1);
- CONVERT_ARG_CHECKED(JSFunction, f, 0);
- return isolate->heap()->ToBoolean(f->shared()->is_arrow());
-}
-
-
-RUNTIME_FUNCTION(Runtime_FunctionIsConciseMethod) {
- SealHandleScope shs(isolate);
- DCHECK(args.length() == 1);
- CONVERT_ARG_CHECKED(JSFunction, f, 0);
- return isolate->heap()->ToBoolean(f->shared()->is_concise_method());
-}
-
-
RUNTIME_FUNCTION(Runtime_FunctionRemovePrototype) {
SealHandleScope shs(isolate);
DCHECK(args.length() == 1);
CONVERT_ARG_CHECKED(JSFunction, f, 0);
RUNTIME_ASSERT(f->RemovePrototype());
+ f->shared()->set_construct_stub(
+ *isolate->builtins()->ConstructedNonConstructable());
return isolate->heap()->undefined_value();
}
@@ -113,23 +52,23 @@ RUNTIME_FUNCTION(Runtime_FunctionRemovePrototype) {
RUNTIME_FUNCTION(Runtime_FunctionGetScript) {
HandleScope scope(isolate);
- DCHECK(args.length() == 1);
+ DCHECK_EQ(1, args.length());
+ CONVERT_ARG_HANDLE_CHECKED(JSReceiver, function, 0);
- CONVERT_ARG_CHECKED(JSFunction, fun, 0);
- Handle<Object> script = Handle<Object>(fun->shared()->script(), isolate);
+ if (function->IsJSBoundFunction()) return isolate->heap()->undefined_value();
+ Handle<Object> script(Handle<JSFunction>::cast(function)->shared()->script(),
+ isolate);
if (!script->IsScript()) return isolate->heap()->undefined_value();
-
return *Script::GetWrapper(Handle<Script>::cast(script));
}
RUNTIME_FUNCTION(Runtime_FunctionGetSourceCode) {
HandleScope scope(isolate);
- DCHECK(args.length() == 1);
-
- CONVERT_ARG_HANDLE_CHECKED(JSFunction, f, 0);
- Handle<SharedFunctionInfo> shared(f->shared());
- return *shared->GetSourceCode();
+ DCHECK_EQ(1, args.length());
+ CONVERT_ARG_HANDLE_CHECKED(JSReceiver, function, 0);
+ if (function->IsJSBoundFunction()) return isolate->heap()->undefined_value();
+ return *Handle<JSFunction>::cast(function)->shared()->GetSourceCode();
}
@@ -203,18 +142,6 @@ RUNTIME_FUNCTION(Runtime_FunctionIsAPIFunction) {
}
-RUNTIME_FUNCTION(Runtime_FunctionHidesSource) {
- SealHandleScope shs(isolate);
- DCHECK(args.length() == 1);
- CONVERT_ARG_CHECKED(JSFunction, f, 0);
-
- SharedFunctionInfo* shared = f->shared();
- bool hide_source = !shared->script()->IsScript() ||
- Script::cast(shared->script())->hide_source();
- return isolate->heap()->ToBoolean(hide_source);
-}
-
-
RUNTIME_FUNCTION(Runtime_SetCode) {
HandleScope scope(isolate);
DCHECK(args.length() == 2);
@@ -224,7 +151,6 @@ RUNTIME_FUNCTION(Runtime_SetCode) {
Handle<SharedFunctionInfo> target_shared(target->shared());
Handle<SharedFunctionInfo> source_shared(source->shared());
- RUNTIME_ASSERT(!source_shared->bound());
if (!Compiler::Compile(source, KEEP_EXCEPTION)) {
return isolate->heap()->exception();
@@ -320,197 +246,25 @@ RUNTIME_FUNCTION(Runtime_SetForceInlineFlag) {
}
-// Find the arguments of the JavaScript function invocation that called
-// into C++ code. Collect these in a newly allocated array of handles (possibly
-// prefixed by a number of empty handles).
-base::SmartArrayPointer<Handle<Object>> Runtime::GetCallerArguments(
- Isolate* isolate, int prefix_argc, int* total_argc) {
- // Find frame containing arguments passed to the caller.
- JavaScriptFrameIterator it(isolate);
- JavaScriptFrame* frame = it.frame();
- List<JSFunction*> functions(2);
- frame->GetFunctions(&functions);
- if (functions.length() > 1) {
- int inlined_jsframe_index = functions.length() - 1;
- TranslatedState translated_values(frame);
- translated_values.Prepare(false, frame->fp());
-
- int argument_count = 0;
- TranslatedFrame* translated_frame =
- translated_values.GetArgumentsInfoFromJSFrameIndex(
- inlined_jsframe_index, &argument_count);
- TranslatedFrame::iterator iter = translated_frame->begin();
-
- // Skip the function.
- iter++;
-
- // Skip the receiver.
- iter++;
- argument_count--;
-
- *total_argc = prefix_argc + argument_count;
- base::SmartArrayPointer<Handle<Object> > param_data(
- NewArray<Handle<Object> >(*total_argc));
- bool should_deoptimize = false;
- for (int i = 0; i < argument_count; i++) {
- should_deoptimize = should_deoptimize || iter->IsMaterializedObject();
- Handle<Object> value = iter->GetValue();
- param_data[prefix_argc + i] = value;
- iter++;
- }
-
- if (should_deoptimize) {
- translated_values.StoreMaterializedValuesAndDeopt();
- }
-
- return param_data;
- } else {
- it.AdvanceToArgumentsFrame();
- frame = it.frame();
- int args_count = frame->ComputeParametersCount();
-
- *total_argc = prefix_argc + args_count;
- base::SmartArrayPointer<Handle<Object> > param_data(
- NewArray<Handle<Object> >(*total_argc));
- for (int i = 0; i < args_count; i++) {
- Handle<Object> val = Handle<Object>(frame->GetParameter(i), isolate);
- param_data[prefix_argc + i] = val;
- }
- return param_data;
- }
-}
-
-
-RUNTIME_FUNCTION(Runtime_FunctionBindArguments) {
- HandleScope scope(isolate);
- DCHECK(args.length() == 4);
- CONVERT_ARG_HANDLE_CHECKED(JSFunction, bound_function, 0);
- CONVERT_ARG_HANDLE_CHECKED(JSReceiver, bindee, 1);
- CONVERT_ARG_HANDLE_CHECKED(Object, this_object, 2);
- CONVERT_NUMBER_ARG_HANDLE_CHECKED(new_length, 3);
-
- // TODO(lrn): Create bound function in C++ code from premade shared info.
- bound_function->shared()->set_bound(true);
- bound_function->shared()->set_optimized_code_map(Smi::FromInt(0));
- bound_function->shared()->set_inferred_name(isolate->heap()->empty_string());
- // Get all arguments of calling function (Function.prototype.bind).
- int argc = 0;
- base::SmartArrayPointer<Handle<Object>> arguments =
- Runtime::GetCallerArguments(isolate, 0, &argc);
- // Don't count the this-arg.
- if (argc > 0) {
- RUNTIME_ASSERT(arguments[0].is_identical_to(this_object));
- argc--;
- } else {
- RUNTIME_ASSERT(this_object->IsUndefined());
- }
- // Initialize array of bindings (function, this, and any existing arguments
- // if the function was already bound).
- Handle<BindingsArray> new_bindings;
- int out_index = 0;
- Handle<TypeFeedbackVector> vector(
- bound_function->shared()->feedback_vector());
- if (bindee->IsJSFunction() && JSFunction::cast(*bindee)->shared()->bound()) {
- Handle<BindingsArray> old_bindings(
- JSFunction::cast(*bindee)->function_bindings());
- RUNTIME_ASSERT(old_bindings->bindings_count() >= 0);
- bindee = handle(old_bindings->bound_function(), isolate);
- Handle<Object> old_bound_this(old_bindings->bound_this(), isolate);
- new_bindings = BindingsArray::New(isolate, vector, bindee, old_bound_this,
- old_bindings->bindings_count() + argc);
- for (int n = old_bindings->bindings_count(); out_index < n; out_index++) {
- new_bindings->set_binding(out_index, old_bindings->binding(out_index));
- }
- } else {
- new_bindings =
- BindingsArray::New(isolate, vector, bindee, this_object, argc);
- }
- // Copy arguments, skipping the first which is "this_arg".
- for (int j = 0; j < argc; j++, out_index++) {
- new_bindings->set_binding(out_index, *arguments[j + 1]);
- }
- new_bindings->set_map_no_write_barrier(isolate->heap()->fixed_array_map());
- bound_function->set_function_bindings(*new_bindings);
-
- // Update length. Have to remove the prototype first so that map migration
- // is happy about the number of fields.
- RUNTIME_ASSERT(bound_function->RemovePrototype());
-
- // The new function should have the same [[Prototype]] as the bindee.
- Handle<Map> bound_function_map =
- bindee->IsConstructor()
- ? isolate->bound_function_with_constructor_map()
- : isolate->bound_function_without_constructor_map();
- PrototypeIterator iter(isolate, bindee);
- Handle<Object> proto = PrototypeIterator::GetCurrent(iter);
- if (bound_function_map->prototype() != *proto) {
- bound_function_map = Map::TransitionToPrototype(bound_function_map, proto,
- REGULAR_PROTOTYPE);
- }
- JSObject::MigrateToMap(bound_function, bound_function_map);
- DCHECK_EQ(bindee->IsConstructor(), bound_function->IsConstructor());
-
- Handle<String> length_string = isolate->factory()->length_string();
- // These attributes must be kept in sync with how the bootstrapper
- // configures the bound_function_map retrieved above.
- // We use ...IgnoreAttributes() here because of length's read-onliness.
- PropertyAttributes attr =
- static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY);
- RETURN_FAILURE_ON_EXCEPTION(
- isolate, JSObject::SetOwnPropertyIgnoreAttributes(
- bound_function, length_string, new_length, attr));
- return *bound_function;
-}
-
-
-RUNTIME_FUNCTION(Runtime_BoundFunctionGetBindings) {
- HandleScope handles(isolate);
- DCHECK(args.length() == 1);
- CONVERT_ARG_HANDLE_CHECKED(JSReceiver, callable, 0);
- if (callable->IsJSFunction()) {
- Handle<JSFunction> function = Handle<JSFunction>::cast(callable);
- if (function->shared()->bound()) {
- RUNTIME_ASSERT(function->function_bindings()->IsBindingsArray());
- Handle<BindingsArray> bindings(function->function_bindings());
- return *BindingsArray::CreateRuntimeBindings(bindings);
- }
- }
- return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_NewObjectFromBound) {
+RUNTIME_FUNCTION(Runtime_Call) {
HandleScope scope(isolate);
- DCHECK(args.length() == 1);
- // First argument is a function to use as a constructor.
- CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
- RUNTIME_ASSERT(function->shared()->bound());
-
- // The argument is a bound function. Extract its bound arguments
- // and callable.
- Handle<BindingsArray> bound_args =
- handle(BindingsArray::cast(function->function_bindings()));
- int bound_argc = bound_args->bindings_count();
- Handle<Object> bound_function(bound_args->bound_function(), isolate);
- DCHECK(!bound_function->IsJSFunction() ||
- !Handle<JSFunction>::cast(bound_function)->shared()->bound());
-
- int total_argc = 0;
- base::SmartArrayPointer<Handle<Object>> param_data =
- Runtime::GetCallerArguments(isolate, bound_argc, &total_argc);
- for (int i = 0; i < bound_argc; i++) {
- param_data[i] = handle(bound_args->binding(i), isolate);
+ DCHECK_LE(2, args.length());
+ int const argc = args.length() - 2;
+ CONVERT_ARG_HANDLE_CHECKED(JSReceiver, target, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 1);
+ ScopedVector<Handle<Object>> argv(argc);
+ for (int i = 0; i < argc; ++i) {
+ argv[i] = args.at<Object>(2 + i);
}
-
Handle<Object> result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
- isolate, result, Execution::New(isolate, bound_function, bound_function,
- total_argc, param_data.get()));
+ isolate, result,
+ Execution::Call(isolate, target, receiver, argc, argv.start()));
return *result;
}
-RUNTIME_FUNCTION(Runtime_Call) {
+RUNTIME_FUNCTION(Runtime_TailCall) {
HandleScope scope(isolate);
DCHECK_LE(2, args.length());
int const argc = args.length() - 2;
@@ -565,18 +319,6 @@ RUNTIME_FUNCTION(Runtime_Apply) {
}
-RUNTIME_FUNCTION(Runtime_GetOriginalConstructor) {
- SealHandleScope shs(isolate);
- DCHECK(args.length() == 0);
- JavaScriptFrameIterator it(isolate);
- JavaScriptFrame* frame = it.frame();
- // Currently we don't inline [[Construct]] calls.
- return frame->IsConstructor() && !frame->HasInlinedFrames()
- ? frame->GetOriginalConstructor()
- : isolate->heap()->undefined_value();
-}
-
-
// ES6 section 9.2.1.2, OrdinaryCallBindThis for sloppy callee.
RUNTIME_FUNCTION(Runtime_ConvertReceiver) {
HandleScope scope(isolate);
@@ -589,20 +331,11 @@ RUNTIME_FUNCTION(Runtime_ConvertReceiver) {
}
-RUNTIME_FUNCTION(Runtime_IsConstructCall) {
- SealHandleScope shs(isolate);
- DCHECK(args.length() == 0);
- JavaScriptFrameIterator it(isolate);
- JavaScriptFrame* frame = it.frame();
- return isolate->heap()->ToBoolean(frame->IsConstructor());
-}
-
-
RUNTIME_FUNCTION(Runtime_IsFunction) {
SealHandleScope shs(isolate);
- DCHECK(args.length() == 1);
- CONVERT_ARG_CHECKED(Object, obj, 0);
- return isolate->heap()->ToBoolean(obj->IsJSFunction());
+ DCHECK_EQ(1, args.length());
+ CONVERT_ARG_CHECKED(Object, object, 0);
+ return isolate->heap()->ToBoolean(object->IsFunction());
}
@@ -613,5 +346,16 @@ RUNTIME_FUNCTION(Runtime_ThrowStrongModeTooFewArguments) {
NewTypeError(MessageTemplate::kStrongArity));
}
+
+RUNTIME_FUNCTION(Runtime_FunctionToString) {
+ HandleScope scope(isolate);
+ DCHECK_EQ(1, args.length());
+ CONVERT_ARG_HANDLE_CHECKED(JSReceiver, function, 0);
+ return function->IsJSBoundFunction()
+ ? *JSBoundFunction::ToString(
+ Handle<JSBoundFunction>::cast(function))
+ : *JSFunction::ToString(Handle<JSFunction>::cast(function));
+}
+
} // namespace internal
} // namespace v8