| OLD | NEW |
| 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/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/api.h" | 7 #include "src/api.h" |
| 8 #include "src/arguments.h" | 8 #include "src/arguments.h" |
| 9 #include "src/base/once.h" | 9 #include "src/base/once.h" |
| 10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 namespace { | 24 namespace { |
| 25 | 25 |
| 26 // Arguments object passed to C++ builtins. | 26 // Arguments object passed to C++ builtins. |
| 27 template <BuiltinExtraArguments extra_args> | 27 template <BuiltinExtraArguments extra_args> |
| 28 class BuiltinArguments : public Arguments { | 28 class BuiltinArguments : public Arguments { |
| 29 public: | 29 public: |
| 30 BuiltinArguments(int length, Object** arguments) | 30 BuiltinArguments(int length, Object** arguments) |
| 31 : Arguments(length, arguments) { } | 31 : Arguments(length, arguments) { } |
| 32 | 32 |
| 33 Object*& operator[] (int index) { | 33 Object*& operator[] (int index) { |
| 34 ASSERT(index < length()); | 34 DCHECK(index < length()); |
| 35 return Arguments::operator[](index); | 35 return Arguments::operator[](index); |
| 36 } | 36 } |
| 37 | 37 |
| 38 template <class S> Handle<S> at(int index) { | 38 template <class S> Handle<S> at(int index) { |
| 39 ASSERT(index < length()); | 39 DCHECK(index < length()); |
| 40 return Arguments::at<S>(index); | 40 return Arguments::at<S>(index); |
| 41 } | 41 } |
| 42 | 42 |
| 43 Handle<Object> receiver() { | 43 Handle<Object> receiver() { |
| 44 return Arguments::at<Object>(0); | 44 return Arguments::at<Object>(0); |
| 45 } | 45 } |
| 46 | 46 |
| 47 Handle<JSFunction> called_function() { | 47 Handle<JSFunction> called_function() { |
| 48 STATIC_ASSERT(extra_args == NEEDS_CALLED_FUNCTION); | 48 STATIC_ASSERT(extra_args == NEEDS_CALLED_FUNCTION); |
| 49 return Arguments::at<JSFunction>(Arguments::length() - 1); | 49 return Arguments::at<JSFunction>(Arguments::length() - 1); |
| 50 } | 50 } |
| 51 | 51 |
| 52 // Gets the total number of arguments including the receiver (but | 52 // Gets the total number of arguments including the receiver (but |
| 53 // excluding extra arguments). | 53 // excluding extra arguments). |
| 54 int length() const { | 54 int length() const { |
| 55 STATIC_ASSERT(extra_args == NO_EXTRA_ARGUMENTS); | 55 STATIC_ASSERT(extra_args == NO_EXTRA_ARGUMENTS); |
| 56 return Arguments::length(); | 56 return Arguments::length(); |
| 57 } | 57 } |
| 58 | 58 |
| 59 #ifdef DEBUG | 59 #ifdef DEBUG |
| 60 void Verify() { | 60 void Verify() { |
| 61 // Check we have at least the receiver. | 61 // Check we have at least the receiver. |
| 62 ASSERT(Arguments::length() >= 1); | 62 DCHECK(Arguments::length() >= 1); |
| 63 } | 63 } |
| 64 #endif | 64 #endif |
| 65 }; | 65 }; |
| 66 | 66 |
| 67 | 67 |
| 68 // Specialize BuiltinArguments for the called function extra argument. | 68 // Specialize BuiltinArguments for the called function extra argument. |
| 69 | 69 |
| 70 template <> | 70 template <> |
| 71 int BuiltinArguments<NEEDS_CALLED_FUNCTION>::length() const { | 71 int BuiltinArguments<NEEDS_CALLED_FUNCTION>::length() const { |
| 72 return Arguments::length() - 1; | 72 return Arguments::length() - 1; |
| 73 } | 73 } |
| 74 | 74 |
| 75 #ifdef DEBUG | 75 #ifdef DEBUG |
| 76 template <> | 76 template <> |
| 77 void BuiltinArguments<NEEDS_CALLED_FUNCTION>::Verify() { | 77 void BuiltinArguments<NEEDS_CALLED_FUNCTION>::Verify() { |
| 78 // Check we have at least the receiver and the called function. | 78 // Check we have at least the receiver and the called function. |
| 79 ASSERT(Arguments::length() >= 2); | 79 DCHECK(Arguments::length() >= 2); |
| 80 // Make sure cast to JSFunction succeeds. | 80 // Make sure cast to JSFunction succeeds. |
| 81 called_function(); | 81 called_function(); |
| 82 } | 82 } |
| 83 #endif | 83 #endif |
| 84 | 84 |
| 85 | 85 |
| 86 #define DEF_ARG_TYPE(name, spec) \ | 86 #define DEF_ARG_TYPE(name, spec) \ |
| 87 typedef BuiltinArguments<spec> name##ArgumentsType; | 87 typedef BuiltinArguments<spec> name##ArgumentsType; |
| 88 BUILTIN_LIST_C(DEF_ARG_TYPE) | 88 BUILTIN_LIST_C(DEF_ARG_TYPE) |
| 89 #undef DEF_ARG_TYPE | 89 #undef DEF_ARG_TYPE |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 131 name##ArgumentsType args, Isolate* isolate) | 131 name##ArgumentsType args, Isolate* isolate) |
| 132 #endif | 132 #endif |
| 133 | 133 |
| 134 | 134 |
| 135 #ifdef DEBUG | 135 #ifdef DEBUG |
| 136 static inline bool CalledAsConstructor(Isolate* isolate) { | 136 static inline bool CalledAsConstructor(Isolate* isolate) { |
| 137 // Calculate the result using a full stack frame iterator and check | 137 // Calculate the result using a full stack frame iterator and check |
| 138 // that the state of the stack is as we assume it to be in the | 138 // that the state of the stack is as we assume it to be in the |
| 139 // code below. | 139 // code below. |
| 140 StackFrameIterator it(isolate); | 140 StackFrameIterator it(isolate); |
| 141 ASSERT(it.frame()->is_exit()); | 141 DCHECK(it.frame()->is_exit()); |
| 142 it.Advance(); | 142 it.Advance(); |
| 143 StackFrame* frame = it.frame(); | 143 StackFrame* frame = it.frame(); |
| 144 bool reference_result = frame->is_construct(); | 144 bool reference_result = frame->is_construct(); |
| 145 Address fp = Isolate::c_entry_fp(isolate->thread_local_top()); | 145 Address fp = Isolate::c_entry_fp(isolate->thread_local_top()); |
| 146 // Because we know fp points to an exit frame we can use the relevant | 146 // Because we know fp points to an exit frame we can use the relevant |
| 147 // part of ExitFrame::ComputeCallerState directly. | 147 // part of ExitFrame::ComputeCallerState directly. |
| 148 const int kCallerOffset = ExitFrameConstants::kCallerFPOffset; | 148 const int kCallerOffset = ExitFrameConstants::kCallerFPOffset; |
| 149 Address caller_fp = Memory::Address_at(fp + kCallerOffset); | 149 Address caller_fp = Memory::Address_at(fp + kCallerOffset); |
| 150 // This inlines the part of StackFrame::ComputeType that grabs the | 150 // This inlines the part of StackFrame::ComputeType that grabs the |
| 151 // type of the current frame. Note that StackFrame::ComputeType | 151 // type of the current frame. Note that StackFrame::ComputeType |
| 152 // has been specialized for each architecture so if any one of them | 152 // has been specialized for each architecture so if any one of them |
| 153 // changes this code has to be changed as well. | 153 // changes this code has to be changed as well. |
| 154 const int kMarkerOffset = StandardFrameConstants::kMarkerOffset; | 154 const int kMarkerOffset = StandardFrameConstants::kMarkerOffset; |
| 155 const Smi* kConstructMarker = Smi::FromInt(StackFrame::CONSTRUCT); | 155 const Smi* kConstructMarker = Smi::FromInt(StackFrame::CONSTRUCT); |
| 156 Object* marker = Memory::Object_at(caller_fp + kMarkerOffset); | 156 Object* marker = Memory::Object_at(caller_fp + kMarkerOffset); |
| 157 bool result = (marker == kConstructMarker); | 157 bool result = (marker == kConstructMarker); |
| 158 ASSERT_EQ(result, reference_result); | 158 DCHECK_EQ(result, reference_result); |
| 159 return result; | 159 return result; |
| 160 } | 160 } |
| 161 #endif | 161 #endif |
| 162 | 162 |
| 163 | 163 |
| 164 // ---------------------------------------------------------------------------- | 164 // ---------------------------------------------------------------------------- |
| 165 | 165 |
| 166 BUILTIN(Illegal) { | 166 BUILTIN(Illegal) { |
| 167 UNREACHABLE(); | 167 UNREACHABLE(); |
| 168 return isolate->heap()->undefined_value(); // Make compiler happy. | 168 return isolate->heap()->undefined_value(); // Make compiler happy. |
| 169 } | 169 } |
| 170 | 170 |
| 171 | 171 |
| 172 BUILTIN(EmptyFunction) { | 172 BUILTIN(EmptyFunction) { |
| 173 return isolate->heap()->undefined_value(); | 173 return isolate->heap()->undefined_value(); |
| 174 } | 174 } |
| 175 | 175 |
| 176 | 176 |
| 177 static void MoveDoubleElements(FixedDoubleArray* dst, int dst_index, | 177 static void MoveDoubleElements(FixedDoubleArray* dst, int dst_index, |
| 178 FixedDoubleArray* src, int src_index, int len) { | 178 FixedDoubleArray* src, int src_index, int len) { |
| 179 if (len == 0) return; | 179 if (len == 0) return; |
| 180 MemMove(dst->data_start() + dst_index, src->data_start() + src_index, | 180 MemMove(dst->data_start() + dst_index, src->data_start() + src_index, |
| 181 len * kDoubleSize); | 181 len * kDoubleSize); |
| 182 } | 182 } |
| 183 | 183 |
| 184 | 184 |
| 185 static FixedArrayBase* LeftTrimFixedArray(Heap* heap, | 185 static FixedArrayBase* LeftTrimFixedArray(Heap* heap, |
| 186 FixedArrayBase* elms, | 186 FixedArrayBase* elms, |
| 187 int to_trim) { | 187 int to_trim) { |
| 188 ASSERT(heap->CanMoveObjectStart(elms)); | 188 DCHECK(heap->CanMoveObjectStart(elms)); |
| 189 | 189 |
| 190 Map* map = elms->map(); | 190 Map* map = elms->map(); |
| 191 int entry_size; | 191 int entry_size; |
| 192 if (elms->IsFixedArray()) { | 192 if (elms->IsFixedArray()) { |
| 193 entry_size = kPointerSize; | 193 entry_size = kPointerSize; |
| 194 } else { | 194 } else { |
| 195 entry_size = kDoubleSize; | 195 entry_size = kDoubleSize; |
| 196 } | 196 } |
| 197 ASSERT(elms->map() != heap->fixed_cow_array_map()); | 197 DCHECK(elms->map() != heap->fixed_cow_array_map()); |
| 198 // For now this trick is only applied to fixed arrays in new and paged space. | 198 // For now this trick is only applied to fixed arrays in new and paged space. |
| 199 // In large object space the object's start must coincide with chunk | 199 // In large object space the object's start must coincide with chunk |
| 200 // and thus the trick is just not applicable. | 200 // and thus the trick is just not applicable. |
| 201 ASSERT(!heap->lo_space()->Contains(elms)); | 201 DCHECK(!heap->lo_space()->Contains(elms)); |
| 202 | 202 |
| 203 STATIC_ASSERT(FixedArrayBase::kMapOffset == 0); | 203 STATIC_ASSERT(FixedArrayBase::kMapOffset == 0); |
| 204 STATIC_ASSERT(FixedArrayBase::kLengthOffset == kPointerSize); | 204 STATIC_ASSERT(FixedArrayBase::kLengthOffset == kPointerSize); |
| 205 STATIC_ASSERT(FixedArrayBase::kHeaderSize == 2 * kPointerSize); | 205 STATIC_ASSERT(FixedArrayBase::kHeaderSize == 2 * kPointerSize); |
| 206 | 206 |
| 207 Object** former_start = HeapObject::RawField(elms, 0); | 207 Object** former_start = HeapObject::RawField(elms, 0); |
| 208 | 208 |
| 209 const int len = elms->length(); | 209 const int len = elms->length(); |
| 210 | 210 |
| 211 if (to_trim * entry_size > FixedArrayBase::kHeaderSize && | 211 if (to_trim * entry_size > FixedArrayBase::kHeaderSize && |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 295 } else { | 295 } else { |
| 296 return MaybeHandle<FixedArrayBase>(); | 296 return MaybeHandle<FixedArrayBase>(); |
| 297 } | 297 } |
| 298 | 298 |
| 299 // Need to ensure that the arguments passed in args can be contained in | 299 // Need to ensure that the arguments passed in args can be contained in |
| 300 // the array. | 300 // the array. |
| 301 int args_length = args->length(); | 301 int args_length = args->length(); |
| 302 if (first_added_arg >= args_length) return handle(array->elements(), isolate); | 302 if (first_added_arg >= args_length) return handle(array->elements(), isolate); |
| 303 | 303 |
| 304 ElementsKind origin_kind = array->map()->elements_kind(); | 304 ElementsKind origin_kind = array->map()->elements_kind(); |
| 305 ASSERT(!IsFastObjectElementsKind(origin_kind)); | 305 DCHECK(!IsFastObjectElementsKind(origin_kind)); |
| 306 ElementsKind target_kind = origin_kind; | 306 ElementsKind target_kind = origin_kind; |
| 307 { | 307 { |
| 308 DisallowHeapAllocation no_gc; | 308 DisallowHeapAllocation no_gc; |
| 309 int arg_count = args->length() - first_added_arg; | 309 int arg_count = args->length() - first_added_arg; |
| 310 Object** arguments = args->arguments() - first_added_arg - (arg_count - 1); | 310 Object** arguments = args->arguments() - first_added_arg - (arg_count - 1); |
| 311 for (int i = 0; i < arg_count; i++) { | 311 for (int i = 0; i < arg_count; i++) { |
| 312 Object* arg = arguments[i]; | 312 Object* arg = arguments[i]; |
| 313 if (arg->IsHeapObject()) { | 313 if (arg->IsHeapObject()) { |
| 314 if (arg->IsHeapNumber()) { | 314 if (arg->IsHeapNumber()) { |
| 315 target_kind = FAST_DOUBLE_ELEMENTS; | 315 target_kind = FAST_DOUBLE_ELEMENTS; |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 378 if (!maybe_elms_obj.ToHandle(&elms_obj)) { | 378 if (!maybe_elms_obj.ToHandle(&elms_obj)) { |
| 379 return CallJsBuiltin(isolate, "ArrayPush", args); | 379 return CallJsBuiltin(isolate, "ArrayPush", args); |
| 380 } | 380 } |
| 381 | 381 |
| 382 Handle<JSArray> array = Handle<JSArray>::cast(receiver); | 382 Handle<JSArray> array = Handle<JSArray>::cast(receiver); |
| 383 int len = Smi::cast(array->length())->value(); | 383 int len = Smi::cast(array->length())->value(); |
| 384 int to_add = args.length() - 1; | 384 int to_add = args.length() - 1; |
| 385 if (to_add > 0 && JSArray::WouldChangeReadOnlyLength(array, len + to_add)) { | 385 if (to_add > 0 && JSArray::WouldChangeReadOnlyLength(array, len + to_add)) { |
| 386 return CallJsBuiltin(isolate, "ArrayPush", args); | 386 return CallJsBuiltin(isolate, "ArrayPush", args); |
| 387 } | 387 } |
| 388 ASSERT(!array->map()->is_observed()); | 388 DCHECK(!array->map()->is_observed()); |
| 389 | 389 |
| 390 ElementsKind kind = array->GetElementsKind(); | 390 ElementsKind kind = array->GetElementsKind(); |
| 391 | 391 |
| 392 if (IsFastSmiOrObjectElementsKind(kind)) { | 392 if (IsFastSmiOrObjectElementsKind(kind)) { |
| 393 Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj); | 393 Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj); |
| 394 if (to_add == 0) { | 394 if (to_add == 0) { |
| 395 return Smi::FromInt(len); | 395 return Smi::FromInt(len); |
| 396 } | 396 } |
| 397 // Currently fixed arrays cannot grow too big, so | 397 // Currently fixed arrays cannot grow too big, so |
| 398 // we should never hit this case. | 398 // we should never hit this case. |
| 399 ASSERT(to_add <= (Smi::kMaxValue - len)); | 399 DCHECK(to_add <= (Smi::kMaxValue - len)); |
| 400 | 400 |
| 401 int new_length = len + to_add; | 401 int new_length = len + to_add; |
| 402 | 402 |
| 403 if (new_length > elms->length()) { | 403 if (new_length > elms->length()) { |
| 404 // New backing storage is needed. | 404 // New backing storage is needed. |
| 405 int capacity = new_length + (new_length >> 1) + 16; | 405 int capacity = new_length + (new_length >> 1) + 16; |
| 406 Handle<FixedArray> new_elms = | 406 Handle<FixedArray> new_elms = |
| 407 isolate->factory()->NewUninitializedFixedArray(capacity); | 407 isolate->factory()->NewUninitializedFixedArray(capacity); |
| 408 | 408 |
| 409 ElementsAccessor* accessor = array->GetElementsAccessor(); | 409 ElementsAccessor* accessor = array->GetElementsAccessor(); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 428 // Set the length. | 428 // Set the length. |
| 429 array->set_length(Smi::FromInt(new_length)); | 429 array->set_length(Smi::FromInt(new_length)); |
| 430 return Smi::FromInt(new_length); | 430 return Smi::FromInt(new_length); |
| 431 } else { | 431 } else { |
| 432 int elms_len = elms_obj->length(); | 432 int elms_len = elms_obj->length(); |
| 433 if (to_add == 0) { | 433 if (to_add == 0) { |
| 434 return Smi::FromInt(len); | 434 return Smi::FromInt(len); |
| 435 } | 435 } |
| 436 // Currently fixed arrays cannot grow too big, so | 436 // Currently fixed arrays cannot grow too big, so |
| 437 // we should never hit this case. | 437 // we should never hit this case. |
| 438 ASSERT(to_add <= (Smi::kMaxValue - len)); | 438 DCHECK(to_add <= (Smi::kMaxValue - len)); |
| 439 | 439 |
| 440 int new_length = len + to_add; | 440 int new_length = len + to_add; |
| 441 | 441 |
| 442 Handle<FixedDoubleArray> new_elms; | 442 Handle<FixedDoubleArray> new_elms; |
| 443 | 443 |
| 444 if (new_length > elms_len) { | 444 if (new_length > elms_len) { |
| 445 // New backing storage is needed. | 445 // New backing storage is needed. |
| 446 int capacity = new_length + (new_length >> 1) + 16; | 446 int capacity = new_length + (new_length >> 1) + 16; |
| 447 // Create new backing store; since capacity > 0, we can | 447 // Create new backing store; since capacity > 0, we can |
| 448 // safely cast to FixedDoubleArray. | 448 // safely cast to FixedDoubleArray. |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 483 HandleScope scope(isolate); | 483 HandleScope scope(isolate); |
| 484 Handle<Object> receiver = args.receiver(); | 484 Handle<Object> receiver = args.receiver(); |
| 485 MaybeHandle<FixedArrayBase> maybe_elms_obj = | 485 MaybeHandle<FixedArrayBase> maybe_elms_obj = |
| 486 EnsureJSArrayWithWritableFastElements(isolate, receiver, NULL, 0); | 486 EnsureJSArrayWithWritableFastElements(isolate, receiver, NULL, 0); |
| 487 Handle<FixedArrayBase> elms_obj; | 487 Handle<FixedArrayBase> elms_obj; |
| 488 if (!maybe_elms_obj.ToHandle(&elms_obj)) { | 488 if (!maybe_elms_obj.ToHandle(&elms_obj)) { |
| 489 return CallJsBuiltin(isolate, "ArrayPop", args); | 489 return CallJsBuiltin(isolate, "ArrayPop", args); |
| 490 } | 490 } |
| 491 | 491 |
| 492 Handle<JSArray> array = Handle<JSArray>::cast(receiver); | 492 Handle<JSArray> array = Handle<JSArray>::cast(receiver); |
| 493 ASSERT(!array->map()->is_observed()); | 493 DCHECK(!array->map()->is_observed()); |
| 494 | 494 |
| 495 int len = Smi::cast(array->length())->value(); | 495 int len = Smi::cast(array->length())->value(); |
| 496 if (len == 0) return isolate->heap()->undefined_value(); | 496 if (len == 0) return isolate->heap()->undefined_value(); |
| 497 | 497 |
| 498 ElementsAccessor* accessor = array->GetElementsAccessor(); | 498 ElementsAccessor* accessor = array->GetElementsAccessor(); |
| 499 int new_length = len - 1; | 499 int new_length = len - 1; |
| 500 Handle<Object> element = | 500 Handle<Object> element = |
| 501 accessor->Get(array, array, new_length, elms_obj).ToHandleChecked(); | 501 accessor->Get(array, array, new_length, elms_obj).ToHandleChecked(); |
| 502 if (element->IsTheHole()) { | 502 if (element->IsTheHole()) { |
| 503 return CallJsBuiltin(isolate, "ArrayPop", args); | 503 return CallJsBuiltin(isolate, "ArrayPop", args); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 515 Handle<Object> receiver = args.receiver(); | 515 Handle<Object> receiver = args.receiver(); |
| 516 MaybeHandle<FixedArrayBase> maybe_elms_obj = | 516 MaybeHandle<FixedArrayBase> maybe_elms_obj = |
| 517 EnsureJSArrayWithWritableFastElements(isolate, receiver, NULL, 0); | 517 EnsureJSArrayWithWritableFastElements(isolate, receiver, NULL, 0); |
| 518 Handle<FixedArrayBase> elms_obj; | 518 Handle<FixedArrayBase> elms_obj; |
| 519 if (!maybe_elms_obj.ToHandle(&elms_obj) || | 519 if (!maybe_elms_obj.ToHandle(&elms_obj) || |
| 520 !IsJSArrayFastElementMovingAllowed(heap, | 520 !IsJSArrayFastElementMovingAllowed(heap, |
| 521 *Handle<JSArray>::cast(receiver))) { | 521 *Handle<JSArray>::cast(receiver))) { |
| 522 return CallJsBuiltin(isolate, "ArrayShift", args); | 522 return CallJsBuiltin(isolate, "ArrayShift", args); |
| 523 } | 523 } |
| 524 Handle<JSArray> array = Handle<JSArray>::cast(receiver); | 524 Handle<JSArray> array = Handle<JSArray>::cast(receiver); |
| 525 ASSERT(!array->map()->is_observed()); | 525 DCHECK(!array->map()->is_observed()); |
| 526 | 526 |
| 527 int len = Smi::cast(array->length())->value(); | 527 int len = Smi::cast(array->length())->value(); |
| 528 if (len == 0) return heap->undefined_value(); | 528 if (len == 0) return heap->undefined_value(); |
| 529 | 529 |
| 530 // Get first element | 530 // Get first element |
| 531 ElementsAccessor* accessor = array->GetElementsAccessor(); | 531 ElementsAccessor* accessor = array->GetElementsAccessor(); |
| 532 Handle<Object> first = | 532 Handle<Object> first = |
| 533 accessor->Get(array, array, 0, elms_obj).ToHandleChecked(); | 533 accessor->Get(array, array, 0, elms_obj).ToHandleChecked(); |
| 534 if (first->IsTheHole()) { | 534 if (first->IsTheHole()) { |
| 535 return CallJsBuiltin(isolate, "ArrayShift", args); | 535 return CallJsBuiltin(isolate, "ArrayShift", args); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 564 Handle<Object> receiver = args.receiver(); | 564 Handle<Object> receiver = args.receiver(); |
| 565 MaybeHandle<FixedArrayBase> maybe_elms_obj = | 565 MaybeHandle<FixedArrayBase> maybe_elms_obj = |
| 566 EnsureJSArrayWithWritableFastElements(isolate, receiver, NULL, 0); | 566 EnsureJSArrayWithWritableFastElements(isolate, receiver, NULL, 0); |
| 567 Handle<FixedArrayBase> elms_obj; | 567 Handle<FixedArrayBase> elms_obj; |
| 568 if (!maybe_elms_obj.ToHandle(&elms_obj) || | 568 if (!maybe_elms_obj.ToHandle(&elms_obj) || |
| 569 !IsJSArrayFastElementMovingAllowed(heap, | 569 !IsJSArrayFastElementMovingAllowed(heap, |
| 570 *Handle<JSArray>::cast(receiver))) { | 570 *Handle<JSArray>::cast(receiver))) { |
| 571 return CallJsBuiltin(isolate, "ArrayUnshift", args); | 571 return CallJsBuiltin(isolate, "ArrayUnshift", args); |
| 572 } | 572 } |
| 573 Handle<JSArray> array = Handle<JSArray>::cast(receiver); | 573 Handle<JSArray> array = Handle<JSArray>::cast(receiver); |
| 574 ASSERT(!array->map()->is_observed()); | 574 DCHECK(!array->map()->is_observed()); |
| 575 if (!array->HasFastSmiOrObjectElements()) { | 575 if (!array->HasFastSmiOrObjectElements()) { |
| 576 return CallJsBuiltin(isolate, "ArrayUnshift", args); | 576 return CallJsBuiltin(isolate, "ArrayUnshift", args); |
| 577 } | 577 } |
| 578 int len = Smi::cast(array->length())->value(); | 578 int len = Smi::cast(array->length())->value(); |
| 579 int to_add = args.length() - 1; | 579 int to_add = args.length() - 1; |
| 580 int new_length = len + to_add; | 580 int new_length = len + to_add; |
| 581 // Currently fixed arrays cannot grow too big, so | 581 // Currently fixed arrays cannot grow too big, so |
| 582 // we should never hit this case. | 582 // we should never hit this case. |
| 583 ASSERT(to_add <= (Smi::kMaxValue - len)); | 583 DCHECK(to_add <= (Smi::kMaxValue - len)); |
| 584 | 584 |
| 585 if (to_add > 0 && JSArray::WouldChangeReadOnlyLength(array, len + to_add)) { | 585 if (to_add > 0 && JSArray::WouldChangeReadOnlyLength(array, len + to_add)) { |
| 586 return CallJsBuiltin(isolate, "ArrayUnshift", args); | 586 return CallJsBuiltin(isolate, "ArrayUnshift", args); |
| 587 } | 587 } |
| 588 | 588 |
| 589 Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj); | 589 Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj); |
| 590 | 590 |
| 591 JSObject::EnsureCanContainElements(array, &args, 1, to_add, | 591 JSObject::EnsureCanContainElements(array, &args, 1, to_add, |
| 592 DONT_ALLOW_DOUBLE_ELEMENTS); | 592 DONT_ALLOW_DOUBLE_ELEMENTS); |
| 593 | 593 |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 670 AllowHeapAllocation allow_allocation; | 670 AllowHeapAllocation allow_allocation; |
| 671 return CallJsBuiltin(isolate, "ArraySlice", args); | 671 return CallJsBuiltin(isolate, "ArraySlice", args); |
| 672 } | 672 } |
| 673 len = Smi::cast(len_obj)->value(); | 673 len = Smi::cast(len_obj)->value(); |
| 674 if (len > object->elements()->length()) { | 674 if (len > object->elements()->length()) { |
| 675 AllowHeapAllocation allow_allocation; | 675 AllowHeapAllocation allow_allocation; |
| 676 return CallJsBuiltin(isolate, "ArraySlice", args); | 676 return CallJsBuiltin(isolate, "ArraySlice", args); |
| 677 } | 677 } |
| 678 } | 678 } |
| 679 | 679 |
| 680 ASSERT(len >= 0); | 680 DCHECK(len >= 0); |
| 681 int n_arguments = args.length() - 1; | 681 int n_arguments = args.length() - 1; |
| 682 | 682 |
| 683 // Note carefully choosen defaults---if argument is missing, | 683 // Note carefully choosen defaults---if argument is missing, |
| 684 // it's undefined which gets converted to 0 for relative_start | 684 // it's undefined which gets converted to 0 for relative_start |
| 685 // and to len for relative_end. | 685 // and to len for relative_end. |
| 686 relative_start = 0; | 686 relative_start = 0; |
| 687 relative_end = len; | 687 relative_end = len; |
| 688 if (n_arguments > 0) { | 688 if (n_arguments > 0) { |
| 689 Object* arg1 = args[1]; | 689 Object* arg1 = args[1]; |
| 690 if (arg1->IsSmi()) { | 690 if (arg1->IsSmi()) { |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 771 Handle<Object> receiver = args.receiver(); | 771 Handle<Object> receiver = args.receiver(); |
| 772 MaybeHandle<FixedArrayBase> maybe_elms_obj = | 772 MaybeHandle<FixedArrayBase> maybe_elms_obj = |
| 773 EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 3); | 773 EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 3); |
| 774 Handle<FixedArrayBase> elms_obj; | 774 Handle<FixedArrayBase> elms_obj; |
| 775 if (!maybe_elms_obj.ToHandle(&elms_obj) || | 775 if (!maybe_elms_obj.ToHandle(&elms_obj) || |
| 776 !IsJSArrayFastElementMovingAllowed(heap, | 776 !IsJSArrayFastElementMovingAllowed(heap, |
| 777 *Handle<JSArray>::cast(receiver))) { | 777 *Handle<JSArray>::cast(receiver))) { |
| 778 return CallJsBuiltin(isolate, "ArraySplice", args); | 778 return CallJsBuiltin(isolate, "ArraySplice", args); |
| 779 } | 779 } |
| 780 Handle<JSArray> array = Handle<JSArray>::cast(receiver); | 780 Handle<JSArray> array = Handle<JSArray>::cast(receiver); |
| 781 ASSERT(!array->map()->is_observed()); | 781 DCHECK(!array->map()->is_observed()); |
| 782 | 782 |
| 783 int len = Smi::cast(array->length())->value(); | 783 int len = Smi::cast(array->length())->value(); |
| 784 | 784 |
| 785 int n_arguments = args.length() - 1; | 785 int n_arguments = args.length() - 1; |
| 786 | 786 |
| 787 int relative_start = 0; | 787 int relative_start = 0; |
| 788 if (n_arguments > 0) { | 788 if (n_arguments > 0) { |
| 789 DisallowHeapAllocation no_gc; | 789 DisallowHeapAllocation no_gc; |
| 790 Object* arg1 = args[1]; | 790 Object* arg1 = args[1]; |
| 791 if (arg1->IsSmi()) { | 791 if (arg1->IsSmi()) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 805 int actual_start = (relative_start < 0) ? Max(len + relative_start, 0) | 805 int actual_start = (relative_start < 0) ? Max(len + relative_start, 0) |
| 806 : Min(relative_start, len); | 806 : Min(relative_start, len); |
| 807 | 807 |
| 808 // SpiderMonkey, TraceMonkey and JSC treat the case where no delete count is | 808 // SpiderMonkey, TraceMonkey and JSC treat the case where no delete count is |
| 809 // given as a request to delete all the elements from the start. | 809 // given as a request to delete all the elements from the start. |
| 810 // And it differs from the case of undefined delete count. | 810 // And it differs from the case of undefined delete count. |
| 811 // This does not follow ECMA-262, but we do the same for | 811 // This does not follow ECMA-262, but we do the same for |
| 812 // compatibility. | 812 // compatibility. |
| 813 int actual_delete_count; | 813 int actual_delete_count; |
| 814 if (n_arguments == 1) { | 814 if (n_arguments == 1) { |
| 815 ASSERT(len - actual_start >= 0); | 815 DCHECK(len - actual_start >= 0); |
| 816 actual_delete_count = len - actual_start; | 816 actual_delete_count = len - actual_start; |
| 817 } else { | 817 } else { |
| 818 int value = 0; // ToInteger(undefined) == 0 | 818 int value = 0; // ToInteger(undefined) == 0 |
| 819 if (n_arguments > 1) { | 819 if (n_arguments > 1) { |
| 820 DisallowHeapAllocation no_gc; | 820 DisallowHeapAllocation no_gc; |
| 821 Object* arg2 = args[2]; | 821 Object* arg2 = args[2]; |
| 822 if (arg2->IsSmi()) { | 822 if (arg2->IsSmi()) { |
| 823 value = Smi::cast(arg2)->value(); | 823 value = Smi::cast(arg2)->value(); |
| 824 } else { | 824 } else { |
| 825 AllowHeapAllocation allow_allocation; | 825 AllowHeapAllocation allow_allocation; |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 912 heap->MoveElements(*elms, actual_start + item_count, | 912 heap->MoveElements(*elms, actual_start + item_count, |
| 913 actual_start + actual_delete_count, | 913 actual_start + actual_delete_count, |
| 914 (len - actual_delete_count - actual_start)); | 914 (len - actual_delete_count - actual_start)); |
| 915 elms->FillWithHoles(new_length, len); | 915 elms->FillWithHoles(new_length, len); |
| 916 } | 916 } |
| 917 } | 917 } |
| 918 } else if (item_count > actual_delete_count) { | 918 } else if (item_count > actual_delete_count) { |
| 919 Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj); | 919 Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj); |
| 920 // Currently fixed arrays cannot grow too big, so | 920 // Currently fixed arrays cannot grow too big, so |
| 921 // we should never hit this case. | 921 // we should never hit this case. |
| 922 ASSERT((item_count - actual_delete_count) <= (Smi::kMaxValue - len)); | 922 DCHECK((item_count - actual_delete_count) <= (Smi::kMaxValue - len)); |
| 923 | 923 |
| 924 // Check if array need to grow. | 924 // Check if array need to grow. |
| 925 if (new_length > elms->length()) { | 925 if (new_length > elms->length()) { |
| 926 // New backing storage is needed. | 926 // New backing storage is needed. |
| 927 int capacity = new_length + (new_length >> 1) + 16; | 927 int capacity = new_length + (new_length >> 1) + 16; |
| 928 Handle<FixedArray> new_elms = | 928 Handle<FixedArray> new_elms = |
| 929 isolate->factory()->NewUninitializedFixedArray(capacity); | 929 isolate->factory()->NewUninitializedFixedArray(capacity); |
| 930 | 930 |
| 931 DisallowHeapAllocation no_gc; | 931 DisallowHeapAllocation no_gc; |
| 932 | 932 |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1010 AllowHeapAllocation allow_allocation; | 1010 AllowHeapAllocation allow_allocation; |
| 1011 return CallJsBuiltin(isolate, "ArrayConcatJS", args); | 1011 return CallJsBuiltin(isolate, "ArrayConcatJS", args); |
| 1012 } | 1012 } |
| 1013 int len = Smi::cast(JSArray::cast(arg)->length())->value(); | 1013 int len = Smi::cast(JSArray::cast(arg)->length())->value(); |
| 1014 | 1014 |
| 1015 // We shouldn't overflow when adding another len. | 1015 // We shouldn't overflow when adding another len. |
| 1016 const int kHalfOfMaxInt = 1 << (kBitsPerInt - 2); | 1016 const int kHalfOfMaxInt = 1 << (kBitsPerInt - 2); |
| 1017 STATIC_ASSERT(FixedArray::kMaxLength < kHalfOfMaxInt); | 1017 STATIC_ASSERT(FixedArray::kMaxLength < kHalfOfMaxInt); |
| 1018 USE(kHalfOfMaxInt); | 1018 USE(kHalfOfMaxInt); |
| 1019 result_len += len; | 1019 result_len += len; |
| 1020 ASSERT(result_len >= 0); | 1020 DCHECK(result_len >= 0); |
| 1021 | 1021 |
| 1022 if (result_len > FixedDoubleArray::kMaxLength) { | 1022 if (result_len > FixedDoubleArray::kMaxLength) { |
| 1023 AllowHeapAllocation allow_allocation; | 1023 AllowHeapAllocation allow_allocation; |
| 1024 return CallJsBuiltin(isolate, "ArrayConcatJS", args); | 1024 return CallJsBuiltin(isolate, "ArrayConcatJS", args); |
| 1025 } | 1025 } |
| 1026 | 1026 |
| 1027 ElementsKind arg_kind = JSArray::cast(arg)->map()->elements_kind(); | 1027 ElementsKind arg_kind = JSArray::cast(arg)->map()->elements_kind(); |
| 1028 has_double = has_double || IsFastDoubleElementsKind(arg_kind); | 1028 has_double = has_double || IsFastDoubleElementsKind(arg_kind); |
| 1029 is_holey = is_holey || IsFastHoleyElementsKind(arg_kind); | 1029 is_holey = is_holey || IsFastHoleyElementsKind(arg_kind); |
| 1030 if (IsMoreGeneralElementsKindTransition(elements_kind, arg_kind)) { | 1030 if (IsMoreGeneralElementsKindTransition(elements_kind, arg_kind)) { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1055 // performance degradation. Revisit this later. | 1055 // performance degradation. Revisit this later. |
| 1056 JSArray* array = JSArray::cast(args[i]); | 1056 JSArray* array = JSArray::cast(args[i]); |
| 1057 int len = Smi::cast(array->length())->value(); | 1057 int len = Smi::cast(array->length())->value(); |
| 1058 ElementsKind from_kind = array->GetElementsKind(); | 1058 ElementsKind from_kind = array->GetElementsKind(); |
| 1059 if (len > 0) { | 1059 if (len > 0) { |
| 1060 accessor->CopyElements(array, 0, from_kind, storage, j, len); | 1060 accessor->CopyElements(array, 0, from_kind, storage, j, len); |
| 1061 j += len; | 1061 j += len; |
| 1062 } | 1062 } |
| 1063 } | 1063 } |
| 1064 | 1064 |
| 1065 ASSERT(j == result_len); | 1065 DCHECK(j == result_len); |
| 1066 | 1066 |
| 1067 return *result_array; | 1067 return *result_array; |
| 1068 } | 1068 } |
| 1069 | 1069 |
| 1070 | 1070 |
| 1071 // ----------------------------------------------------------------------------- | 1071 // ----------------------------------------------------------------------------- |
| 1072 // Generator and strict mode poison pills | 1072 // Generator and strict mode poison pills |
| 1073 | 1073 |
| 1074 | 1074 |
| 1075 BUILTIN(StrictModePoisonPill) { | 1075 BUILTIN(StrictModePoisonPill) { |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1145 if (current == heap->null_value()) current = heap->undefined_value(); | 1145 if (current == heap->null_value()) current = heap->undefined_value(); |
| 1146 *arg = current; | 1146 *arg = current; |
| 1147 } | 1147 } |
| 1148 return holder; | 1148 return holder; |
| 1149 } | 1149 } |
| 1150 | 1150 |
| 1151 | 1151 |
| 1152 template <bool is_construct> | 1152 template <bool is_construct> |
| 1153 MUST_USE_RESULT static Object* HandleApiCallHelper( | 1153 MUST_USE_RESULT static Object* HandleApiCallHelper( |
| 1154 BuiltinArguments<NEEDS_CALLED_FUNCTION> args, Isolate* isolate) { | 1154 BuiltinArguments<NEEDS_CALLED_FUNCTION> args, Isolate* isolate) { |
| 1155 ASSERT(is_construct == CalledAsConstructor(isolate)); | 1155 DCHECK(is_construct == CalledAsConstructor(isolate)); |
| 1156 Heap* heap = isolate->heap(); | 1156 Heap* heap = isolate->heap(); |
| 1157 | 1157 |
| 1158 HandleScope scope(isolate); | 1158 HandleScope scope(isolate); |
| 1159 Handle<JSFunction> function = args.called_function(); | 1159 Handle<JSFunction> function = args.called_function(); |
| 1160 ASSERT(function->shared()->IsApiFunction()); | 1160 DCHECK(function->shared()->IsApiFunction()); |
| 1161 | 1161 |
| 1162 Handle<FunctionTemplateInfo> fun_data( | 1162 Handle<FunctionTemplateInfo> fun_data( |
| 1163 function->shared()->get_api_func_data(), isolate); | 1163 function->shared()->get_api_func_data(), isolate); |
| 1164 if (is_construct) { | 1164 if (is_construct) { |
| 1165 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 1165 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
| 1166 isolate, fun_data, | 1166 isolate, fun_data, |
| 1167 isolate->factory()->ConfigureInstance( | 1167 isolate->factory()->ConfigureInstance( |
| 1168 fun_data, Handle<JSObject>::cast(args.receiver()))); | 1168 fun_data, Handle<JSObject>::cast(args.receiver()))); |
| 1169 } | 1169 } |
| 1170 | 1170 |
| 1171 SharedFunctionInfo* shared = function->shared(); | 1171 SharedFunctionInfo* shared = function->shared(); |
| 1172 if (shared->strict_mode() == SLOPPY && !shared->native()) { | 1172 if (shared->strict_mode() == SLOPPY && !shared->native()) { |
| 1173 Object* recv = args[0]; | 1173 Object* recv = args[0]; |
| 1174 ASSERT(!recv->IsNull()); | 1174 DCHECK(!recv->IsNull()); |
| 1175 if (recv->IsUndefined()) args[0] = function->global_proxy(); | 1175 if (recv->IsUndefined()) args[0] = function->global_proxy(); |
| 1176 } | 1176 } |
| 1177 | 1177 |
| 1178 Object* raw_holder = TypeCheck(heap, args.length(), &args[0], *fun_data); | 1178 Object* raw_holder = TypeCheck(heap, args.length(), &args[0], *fun_data); |
| 1179 | 1179 |
| 1180 if (raw_holder->IsNull()) { | 1180 if (raw_holder->IsNull()) { |
| 1181 // This function cannot be called with the given receiver. Abort! | 1181 // This function cannot be called with the given receiver. Abort! |
| 1182 Handle<Object> obj = | 1182 Handle<Object> obj = |
| 1183 isolate->factory()->NewTypeError( | 1183 isolate->factory()->NewTypeError( |
| 1184 "illegal_invocation", HandleVector(&function, 1)); | 1184 "illegal_invocation", HandleVector(&function, 1)); |
| 1185 return isolate->Throw(*obj); | 1185 return isolate->Throw(*obj); |
| 1186 } | 1186 } |
| 1187 | 1187 |
| 1188 Object* raw_call_data = fun_data->call_code(); | 1188 Object* raw_call_data = fun_data->call_code(); |
| 1189 if (!raw_call_data->IsUndefined()) { | 1189 if (!raw_call_data->IsUndefined()) { |
| 1190 CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data); | 1190 CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data); |
| 1191 Object* callback_obj = call_data->callback(); | 1191 Object* callback_obj = call_data->callback(); |
| 1192 v8::FunctionCallback callback = | 1192 v8::FunctionCallback callback = |
| 1193 v8::ToCData<v8::FunctionCallback>(callback_obj); | 1193 v8::ToCData<v8::FunctionCallback>(callback_obj); |
| 1194 Object* data_obj = call_data->data(); | 1194 Object* data_obj = call_data->data(); |
| 1195 Object* result; | 1195 Object* result; |
| 1196 | 1196 |
| 1197 LOG(isolate, ApiObjectAccess("call", JSObject::cast(*args.receiver()))); | 1197 LOG(isolate, ApiObjectAccess("call", JSObject::cast(*args.receiver()))); |
| 1198 ASSERT(raw_holder->IsJSObject()); | 1198 DCHECK(raw_holder->IsJSObject()); |
| 1199 | 1199 |
| 1200 FunctionCallbackArguments custom(isolate, | 1200 FunctionCallbackArguments custom(isolate, |
| 1201 data_obj, | 1201 data_obj, |
| 1202 *function, | 1202 *function, |
| 1203 raw_holder, | 1203 raw_holder, |
| 1204 &args[0] - 1, | 1204 &args[0] - 1, |
| 1205 args.length() - 1, | 1205 args.length() - 1, |
| 1206 is_construct); | 1206 is_construct); |
| 1207 | 1207 |
| 1208 v8::Handle<v8::Value> value = custom.Call(callback); | 1208 v8::Handle<v8::Value> value = custom.Call(callback); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1233 | 1233 |
| 1234 // Helper function to handle calls to non-function objects created through the | 1234 // Helper function to handle calls to non-function objects created through the |
| 1235 // API. The object can be called as either a constructor (using new) or just as | 1235 // API. The object can be called as either a constructor (using new) or just as |
| 1236 // a function (without new). | 1236 // a function (without new). |
| 1237 MUST_USE_RESULT static Object* HandleApiCallAsFunctionOrConstructor( | 1237 MUST_USE_RESULT static Object* HandleApiCallAsFunctionOrConstructor( |
| 1238 Isolate* isolate, | 1238 Isolate* isolate, |
| 1239 bool is_construct_call, | 1239 bool is_construct_call, |
| 1240 BuiltinArguments<NO_EXTRA_ARGUMENTS> args) { | 1240 BuiltinArguments<NO_EXTRA_ARGUMENTS> args) { |
| 1241 // Non-functions are never called as constructors. Even if this is an object | 1241 // Non-functions are never called as constructors. Even if this is an object |
| 1242 // called as a constructor the delegate call is not a construct call. | 1242 // called as a constructor the delegate call is not a construct call. |
| 1243 ASSERT(!CalledAsConstructor(isolate)); | 1243 DCHECK(!CalledAsConstructor(isolate)); |
| 1244 Heap* heap = isolate->heap(); | 1244 Heap* heap = isolate->heap(); |
| 1245 | 1245 |
| 1246 Handle<Object> receiver = args.receiver(); | 1246 Handle<Object> receiver = args.receiver(); |
| 1247 | 1247 |
| 1248 // Get the object called. | 1248 // Get the object called. |
| 1249 JSObject* obj = JSObject::cast(*receiver); | 1249 JSObject* obj = JSObject::cast(*receiver); |
| 1250 | 1250 |
| 1251 // Get the invocation callback from the function descriptor that was | 1251 // Get the invocation callback from the function descriptor that was |
| 1252 // used to create the called object. | 1252 // used to create the called object. |
| 1253 ASSERT(obj->map()->has_instance_call_handler()); | 1253 DCHECK(obj->map()->has_instance_call_handler()); |
| 1254 JSFunction* constructor = JSFunction::cast(obj->map()->constructor()); | 1254 JSFunction* constructor = JSFunction::cast(obj->map()->constructor()); |
| 1255 ASSERT(constructor->shared()->IsApiFunction()); | 1255 DCHECK(constructor->shared()->IsApiFunction()); |
| 1256 Object* handler = | 1256 Object* handler = |
| 1257 constructor->shared()->get_api_func_data()->instance_call_handler(); | 1257 constructor->shared()->get_api_func_data()->instance_call_handler(); |
| 1258 ASSERT(!handler->IsUndefined()); | 1258 DCHECK(!handler->IsUndefined()); |
| 1259 CallHandlerInfo* call_data = CallHandlerInfo::cast(handler); | 1259 CallHandlerInfo* call_data = CallHandlerInfo::cast(handler); |
| 1260 Object* callback_obj = call_data->callback(); | 1260 Object* callback_obj = call_data->callback(); |
| 1261 v8::FunctionCallback callback = | 1261 v8::FunctionCallback callback = |
| 1262 v8::ToCData<v8::FunctionCallback>(callback_obj); | 1262 v8::ToCData<v8::FunctionCallback>(callback_obj); |
| 1263 | 1263 |
| 1264 // Get the data for the call and perform the callback. | 1264 // Get the data for the call and perform the callback. |
| 1265 Object* result; | 1265 Object* result; |
| 1266 { | 1266 { |
| 1267 HandleScope scope(isolate); | 1267 HandleScope scope(isolate); |
| 1268 LOG(isolate, ApiObjectAccess("call non-function", obj)); | 1268 LOG(isolate, ApiObjectAccess("call non-function", obj)); |
| (...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1594 BUILTIN_LIST_A(DEF_FUNCTION_PTR_A) | 1594 BUILTIN_LIST_A(DEF_FUNCTION_PTR_A) |
| 1595 BUILTIN_LIST_H(DEF_FUNCTION_PTR_H) | 1595 BUILTIN_LIST_H(DEF_FUNCTION_PTR_H) |
| 1596 BUILTIN_LIST_DEBUG_A(DEF_FUNCTION_PTR_A) | 1596 BUILTIN_LIST_DEBUG_A(DEF_FUNCTION_PTR_A) |
| 1597 | 1597 |
| 1598 #undef DEF_FUNCTION_PTR_C | 1598 #undef DEF_FUNCTION_PTR_C |
| 1599 #undef DEF_FUNCTION_PTR_A | 1599 #undef DEF_FUNCTION_PTR_A |
| 1600 } | 1600 } |
| 1601 | 1601 |
| 1602 | 1602 |
| 1603 void Builtins::SetUp(Isolate* isolate, bool create_heap_objects) { | 1603 void Builtins::SetUp(Isolate* isolate, bool create_heap_objects) { |
| 1604 ASSERT(!initialized_); | 1604 DCHECK(!initialized_); |
| 1605 | 1605 |
| 1606 // Create a scope for the handles in the builtins. | 1606 // Create a scope for the handles in the builtins. |
| 1607 HandleScope scope(isolate); | 1607 HandleScope scope(isolate); |
| 1608 | 1608 |
| 1609 const BuiltinDesc* functions = builtin_function_table.functions(); | 1609 const BuiltinDesc* functions = builtin_function_table.functions(); |
| 1610 | 1610 |
| 1611 // For now we generate builtin adaptor code into a stack-allocated | 1611 // For now we generate builtin adaptor code into a stack-allocated |
| 1612 // buffer, before copying it into individual code objects. Be careful | 1612 // buffer, before copying it into individual code objects. Be careful |
| 1613 // with alignment, some platforms don't like unaligned code. | 1613 // with alignment, some platforms don't like unaligned code. |
| 1614 #ifdef DEBUG | 1614 #ifdef DEBUG |
| 1615 // We can generate a lot of debug code on Arm64. | 1615 // We can generate a lot of debug code on Arm64. |
| 1616 const size_t buffer_size = 32*KB; | 1616 const size_t buffer_size = 32*KB; |
| 1617 #else | 1617 #else |
| 1618 const size_t buffer_size = 8*KB; | 1618 const size_t buffer_size = 8*KB; |
| 1619 #endif | 1619 #endif |
| 1620 union { int force_alignment; byte buffer[buffer_size]; } u; | 1620 union { int force_alignment; byte buffer[buffer_size]; } u; |
| 1621 | 1621 |
| 1622 // Traverse the list of builtins and generate an adaptor in a | 1622 // Traverse the list of builtins and generate an adaptor in a |
| 1623 // separate code object for each one. | 1623 // separate code object for each one. |
| 1624 for (int i = 0; i < builtin_count; i++) { | 1624 for (int i = 0; i < builtin_count; i++) { |
| 1625 if (create_heap_objects) { | 1625 if (create_heap_objects) { |
| 1626 MacroAssembler masm(isolate, u.buffer, sizeof u.buffer); | 1626 MacroAssembler masm(isolate, u.buffer, sizeof u.buffer); |
| 1627 // Generate the code/adaptor. | 1627 // Generate the code/adaptor. |
| 1628 typedef void (*Generator)(MacroAssembler*, int, BuiltinExtraArguments); | 1628 typedef void (*Generator)(MacroAssembler*, int, BuiltinExtraArguments); |
| 1629 Generator g = FUNCTION_CAST<Generator>(functions[i].generator); | 1629 Generator g = FUNCTION_CAST<Generator>(functions[i].generator); |
| 1630 // We pass all arguments to the generator, but it may not use all of | 1630 // We pass all arguments to the generator, but it may not use all of |
| 1631 // them. This works because the first arguments are on top of the | 1631 // them. This works because the first arguments are on top of the |
| 1632 // stack. | 1632 // stack. |
| 1633 ASSERT(!masm.has_frame()); | 1633 DCHECK(!masm.has_frame()); |
| 1634 g(&masm, functions[i].name, functions[i].extra_args); | 1634 g(&masm, functions[i].name, functions[i].extra_args); |
| 1635 // Move the code into the object heap. | 1635 // Move the code into the object heap. |
| 1636 CodeDesc desc; | 1636 CodeDesc desc; |
| 1637 masm.GetCode(&desc); | 1637 masm.GetCode(&desc); |
| 1638 Code::Flags flags = functions[i].flags; | 1638 Code::Flags flags = functions[i].flags; |
| 1639 Handle<Code> code = | 1639 Handle<Code> code = |
| 1640 isolate->factory()->NewCode(desc, flags, masm.CodeObject()); | 1640 isolate->factory()->NewCode(desc, flags, masm.CodeObject()); |
| 1641 // Log the event and add the code to the builtins array. | 1641 // Log the event and add the code to the builtins array. |
| 1642 PROFILE(isolate, | 1642 PROFILE(isolate, |
| 1643 CodeCreateEvent(Logger::BUILTIN_TAG, *code, functions[i].s_name)); | 1643 CodeCreateEvent(Logger::BUILTIN_TAG, *code, functions[i].s_name)); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1718 } | 1718 } |
| 1719 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C) | 1719 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C) |
| 1720 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A) | 1720 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A) |
| 1721 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) | 1721 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) |
| 1722 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) | 1722 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) |
| 1723 #undef DEFINE_BUILTIN_ACCESSOR_C | 1723 #undef DEFINE_BUILTIN_ACCESSOR_C |
| 1724 #undef DEFINE_BUILTIN_ACCESSOR_A | 1724 #undef DEFINE_BUILTIN_ACCESSOR_A |
| 1725 | 1725 |
| 1726 | 1726 |
| 1727 } } // namespace v8::internal | 1727 } } // namespace v8::internal |
| OLD | NEW |