1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "src/builtins/builtins.h"
6 #include "src/builtins/builtins-utils.h"
7 #include "src/interface-descriptors.h"
8 #include "src/macro-assembler.h"
9 
10 namespace v8 {
11 namespace internal {
12 
BUILTIN(Illegal)13 BUILTIN(Illegal) {
14   UNREACHABLE();
15   return isolate->heap()->undefined_value();  // Make compiler happy.
16 }
17 
BUILTIN(EmptyFunction)18 BUILTIN(EmptyFunction) { return isolate->heap()->undefined_value(); }
19 
BUILTIN(UnsupportedThrower)20 BUILTIN(UnsupportedThrower) {
21   HandleScope scope(isolate);
22   THROW_NEW_ERROR_RETURN_FAILURE(isolate,
23                                  NewError(MessageTemplate::kUnsupported));
24 }
25 
26 // -----------------------------------------------------------------------------
27 // Throwers for restricted function properties and strict arguments object
28 // properties
29 
BUILTIN(RestrictedFunctionPropertiesThrower)30 BUILTIN(RestrictedFunctionPropertiesThrower) {
31   HandleScope scope(isolate);
32   THROW_NEW_ERROR_RETURN_FAILURE(
33       isolate, NewTypeError(MessageTemplate::kRestrictedFunctionProperties));
34 }
35 
BUILTIN(RestrictedStrictArgumentsPropertiesThrower)36 BUILTIN(RestrictedStrictArgumentsPropertiesThrower) {
37   HandleScope scope(isolate);
38   THROW_NEW_ERROR_RETURN_FAILURE(
39       isolate, NewTypeError(MessageTemplate::kStrictPoisonPill));
40 }
41 
42 // -----------------------------------------------------------------------------
43 // Interrupt and stack checks.
44 
Generate_InterruptCheck(MacroAssembler * masm)45 void Builtins::Generate_InterruptCheck(MacroAssembler* masm) {
46   masm->TailCallRuntime(Runtime::kInterrupt);
47 }
48 
Generate_StackCheck(MacroAssembler * masm)49 void Builtins::Generate_StackCheck(MacroAssembler* masm) {
50   masm->TailCallRuntime(Runtime::kStackGuard);
51 }
52 
53 // -----------------------------------------------------------------------------
54 // TurboFan support builtins.
55 
Generate_CopyFastSmiOrObjectElements(CodeStubAssembler * assembler)56 void Builtins::Generate_CopyFastSmiOrObjectElements(
57     CodeStubAssembler* assembler) {
58   typedef CodeStubAssembler::Label Label;
59   typedef compiler::Node Node;
60   typedef CopyFastSmiOrObjectElementsDescriptor Descriptor;
61 
62   Node* object = assembler->Parameter(Descriptor::kObject);
63 
64   // Load the {object}s elements.
65   Node* source = assembler->LoadObjectField(object, JSObject::kElementsOffset);
66 
67   CodeStubAssembler::ParameterMode mode = assembler->OptimalParameterMode();
68   Node* length = assembler->UntagParameter(
69       assembler->LoadFixedArrayBaseLength(source), mode);
70 
71   // Check if we can allocate in new space.
72   ElementsKind kind = FAST_ELEMENTS;
73   int max_elements = FixedArrayBase::GetMaxLengthForNewSpaceAllocation(kind);
74   Label if_newspace(assembler), if_oldspace(assembler);
75   assembler->Branch(
76       assembler->UintPtrLessThan(
77           length, assembler->IntPtrOrSmiConstant(max_elements, mode)),
78       &if_newspace, &if_oldspace);
79 
80   assembler->Bind(&if_newspace);
81   {
82     Node* target = assembler->AllocateFixedArray(kind, length, mode);
83     assembler->CopyFixedArrayElements(kind, source, target, length,
84                                       SKIP_WRITE_BARRIER, mode);
85     assembler->StoreObjectField(object, JSObject::kElementsOffset, target);
86     assembler->Return(target);
87   }
88 
89   assembler->Bind(&if_oldspace);
90   {
91     Node* target = assembler->AllocateFixedArray(
92         kind, length, mode, CodeStubAssembler::kPretenured);
93     assembler->CopyFixedArrayElements(kind, source, target, length,
94                                       UPDATE_WRITE_BARRIER, mode);
95     assembler->StoreObjectField(object, JSObject::kElementsOffset, target);
96     assembler->Return(target);
97   }
98 }
99 
Generate_GrowFastDoubleElements(CodeStubAssembler * assembler)100 void Builtins::Generate_GrowFastDoubleElements(CodeStubAssembler* assembler) {
101   typedef CodeStubAssembler::Label Label;
102   typedef compiler::Node Node;
103   typedef GrowArrayElementsDescriptor Descriptor;
104 
105   Node* object = assembler->Parameter(Descriptor::kObject);
106   Node* key = assembler->Parameter(Descriptor::kKey);
107   Node* context = assembler->Parameter(Descriptor::kContext);
108 
109   Label runtime(assembler, CodeStubAssembler::Label::kDeferred);
110   Node* elements = assembler->LoadElements(object);
111   elements = assembler->TryGrowElementsCapacity(
112       object, elements, FAST_DOUBLE_ELEMENTS, key, &runtime);
113   assembler->Return(elements);
114 
115   assembler->Bind(&runtime);
116   assembler->TailCallRuntime(Runtime::kGrowArrayElements, context, object, key);
117 }
118 
Generate_GrowFastSmiOrObjectElements(CodeStubAssembler * assembler)119 void Builtins::Generate_GrowFastSmiOrObjectElements(
120     CodeStubAssembler* assembler) {
121   typedef CodeStubAssembler::Label Label;
122   typedef compiler::Node Node;
123   typedef GrowArrayElementsDescriptor Descriptor;
124 
125   Node* object = assembler->Parameter(Descriptor::kObject);
126   Node* key = assembler->Parameter(Descriptor::kKey);
127   Node* context = assembler->Parameter(Descriptor::kContext);
128 
129   Label runtime(assembler, CodeStubAssembler::Label::kDeferred);
130   Node* elements = assembler->LoadElements(object);
131   elements = assembler->TryGrowElementsCapacity(object, elements, FAST_ELEMENTS,
132                                                 key, &runtime);
133   assembler->Return(elements);
134 
135   assembler->Bind(&runtime);
136   assembler->TailCallRuntime(Runtime::kGrowArrayElements, context, object, key);
137 }
138 
139 }  // namespace internal
140 }  // namespace v8
141