//
-Object* Accessors::FunctionGetLength(Isolate* isolate,
- Object* object,
- void*) {
- JSFunction* function = FindInstanceOf<JSFunction>(isolate, object);
- if (function == NULL) return Smi::FromInt(0);
- // Check if already compiled.
- if (function->shared()->is_compiled()) {
- return Smi::FromInt(function->shared()->length());
- }
- // If the function isn't compiled yet, the length is not computed correctly
- // yet. Compile it now and return the right length.
+void Accessors::FunctionLengthGetter(
+ v8::Local<v8::String> name,
+ const v8::PropertyCallbackInfo<v8::Value>& info) {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
HandleScope scope(isolate);
- Handle<JSFunction> function_handle(function);
- if (Compiler::EnsureCompiled(function_handle, KEEP_EXCEPTION)) {
- return Smi::FromInt(function_handle->shared()->length());
+ Handle<Object> object = Utils::OpenHandle(*info.This());
+ MaybeHandle<JSFunction> maybe_function;
+
+ {
+ DisallowHeapAllocation no_allocation;
+ JSFunction* function = FindInstanceOf<JSFunction>(isolate, *object);
+ if (function != NULL) maybe_function = Handle<JSFunction>(function);
+ }
+
+ int length = 0;
+ Handle<JSFunction> function;
+ if (maybe_function.ToHandle(&function)) {
+ if (function->shared()->is_compiled()) {
+ length = function->shared()->length();
+ } else {
+ // If the function isn't compiled yet, the length is not computed
+ // correctly yet. Compile it now and return the right length.
+ if (Compiler::EnsureCompiled(function, KEEP_EXCEPTION)) {
+ length = function->shared()->length();
+ }
+ if (isolate->has_pending_exception()) {
+ isolate->OptionalRescheduleException(false);
+ }
+ }
}
- return isolate->heap()->exception();
+ Handle<Object> result(Smi::FromInt(length), isolate);
+ info.GetReturnValue().Set(Utils::ToLocal(result));
}
-const AccessorDescriptor Accessors::FunctionLength = {
- FunctionGetLength,
- ReadOnlySetAccessor,
- 0
-};
+void Accessors::FunctionLengthSetter(
+ v8::Local<v8::String> name,
+ v8::Local<v8::Value> val,
+ const v8::PropertyCallbackInfo<void>& info) {
+ // Do nothing.
+}
+
+
+Handle<AccessorInfo> Accessors::FunctionLengthInfo(
+ Isolate* isolate, PropertyAttributes attributes) {
+ return MakeAccessor(isolate,
+ isolate->factory()->length_string(),
+ &FunctionLengthGetter,
+ &FunctionLengthSetter,
+ attributes);
+}
//
// The list of accessor descriptors. This is a second-order macro
// taking a macro to be applied to all accessor descriptor names.
#define ACCESSOR_DESCRIPTOR_LIST(V) \
- V(FunctionLength) \
V(FunctionName) \
V(FunctionArguments) \
V(FunctionCaller) \
V(ArrayLength)
#define ACCESSOR_INFO_LIST(V) \
+ V(FunctionLength) \
V(FunctionPrototype) \
V(ScriptColumnOffset) \
V(ScriptCompilationType) \
int size = (prototypeMode == DONT_ADD_PROTOTYPE) ? 4 : 5;
Map::EnsureDescriptorSlack(map, size);
- Handle<Foreign> length(factory()->NewForeign(&Accessors::FunctionLength));
Handle<Foreign> name(factory()->NewForeign(&Accessors::FunctionName));
Handle<Foreign> args(factory()->NewForeign(&Accessors::FunctionArguments));
Handle<Foreign> caller(factory()->NewForeign(&Accessors::FunctionCaller));
PropertyAttributes attribs = static_cast<PropertyAttributes>(
DONT_ENUM | DONT_DELETE | READ_ONLY);
+ Handle<AccessorInfo> length =
+ Accessors::FunctionLengthInfo(isolate(), attribs);
{ // Add length.
- CallbacksDescriptor d(factory()->length_string(), length, attribs);
+ CallbacksDescriptor d(Handle<Name>(Name::cast(length->name())),
+ length, attribs);
map->AppendDescriptor(&d);
}
{ // Add name.
int size = (prototypeMode == DONT_ADD_PROTOTYPE) ? 4 : 5;
Map::EnsureDescriptorSlack(map, size);
- Handle<Foreign> length(factory()->NewForeign(&Accessors::FunctionLength));
Handle<Foreign> name(factory()->NewForeign(&Accessors::FunctionName));
Handle<AccessorPair> arguments(factory()->NewAccessorPair());
Handle<AccessorPair> caller(factory()->NewAccessorPair());
PropertyAttributes ro_attribs =
static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
+ Handle<AccessorInfo> length =
+ Accessors::FunctionLengthInfo(isolate(), ro_attribs);
{ // Add length.
- CallbacksDescriptor d(factory()->length_string(), length, ro_attribs);
+ CallbacksDescriptor d(Handle<Name>(Name::cast(length->name())),
+ length, ro_attribs);
map->AppendDescriptor(&d);
}
{ // Add name.
--- /dev/null
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --harmony-scoping
+
+function foo(a, b, c, d) {
+ "use strict"
+ const x = 10;
+ // long comment to trigger lazy compilation.
+ // long comment to trigger lazy compilation.
+ // long comment to trigger lazy compilation.
+ // long comment to trigger lazy compilation.
+ // long comment to trigger lazy compilation.
+ // long comment to trigger lazy compilation.
+ // long comment to trigger lazy compilation.
+ // long comment to trigger lazy compilation.
+ // long comment to trigger lazy compilation.
+ // long comment to trigger lazy compilation.
+ // long comment to trigger lazy compilation.
+ // long comment to trigger lazy compilation.
+ // long comment to trigger lazy compilation.
+ // long comment to trigger lazy compilation.
+ // long comment to trigger lazy compilation.
+ // long comment to trigger lazy compilation.
+ // long comment to trigger lazy compilation.
+ // long comment to trigger lazy compilation.
+ // long comment to trigger lazy compilation.
+ // long comment to trigger lazy compilation.
+ // long comment to trigger lazy compilation.
+ // long comment to trigger lazy compilation.
+ x = 20; // This will trigger compile error with harmony scoping.
+}
+
+assertThrows("foo.length()");