• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
8 #include "src/code-factory.h"
9 #include "src/compiler.h"
10 #include "src/uri.h"
11 
12 namespace v8 {
13 namespace internal {
14 
15 // ES6 section 18.2.6.2 decodeURI (encodedURI)
BUILTIN(GlobalDecodeURI)16 BUILTIN(GlobalDecodeURI) {
17   HandleScope scope(isolate);
18   Handle<String> encoded_uri;
19   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
20       isolate, encoded_uri,
21       Object::ToString(isolate, args.atOrUndefined(isolate, 1)));
22 
23   RETURN_RESULT_OR_FAILURE(isolate, Uri::DecodeUri(isolate, encoded_uri));
24 }
25 
26 // ES6 section 18.2.6.3 decodeURIComponent (encodedURIComponent)
BUILTIN(GlobalDecodeURIComponent)27 BUILTIN(GlobalDecodeURIComponent) {
28   HandleScope scope(isolate);
29   Handle<String> encoded_uri_component;
30   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
31       isolate, encoded_uri_component,
32       Object::ToString(isolate, args.atOrUndefined(isolate, 1)));
33 
34   RETURN_RESULT_OR_FAILURE(
35       isolate, Uri::DecodeUriComponent(isolate, encoded_uri_component));
36 }
37 
38 // ES6 section 18.2.6.4 encodeURI (uri)
BUILTIN(GlobalEncodeURI)39 BUILTIN(GlobalEncodeURI) {
40   HandleScope scope(isolate);
41   Handle<String> uri;
42   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
43       isolate, uri, Object::ToString(isolate, args.atOrUndefined(isolate, 1)));
44 
45   RETURN_RESULT_OR_FAILURE(isolate, Uri::EncodeUri(isolate, uri));
46 }
47 
48 // ES6 section 18.2.6.5 encodeURIComponenet (uriComponent)
BUILTIN(GlobalEncodeURIComponent)49 BUILTIN(GlobalEncodeURIComponent) {
50   HandleScope scope(isolate);
51   Handle<String> uri_component;
52   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
53       isolate, uri_component,
54       Object::ToString(isolate, args.atOrUndefined(isolate, 1)));
55 
56   RETURN_RESULT_OR_FAILURE(isolate,
57                            Uri::EncodeUriComponent(isolate, uri_component));
58 }
59 
60 // ES6 section B.2.1.1 escape (string)
BUILTIN(GlobalEscape)61 BUILTIN(GlobalEscape) {
62   HandleScope scope(isolate);
63   Handle<String> string;
64   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
65       isolate, string,
66       Object::ToString(isolate, args.atOrUndefined(isolate, 1)));
67 
68   RETURN_RESULT_OR_FAILURE(isolate, Uri::Escape(isolate, string));
69 }
70 
71 // ES6 section B.2.1.2 unescape (string)
BUILTIN(GlobalUnescape)72 BUILTIN(GlobalUnescape) {
73   HandleScope scope(isolate);
74   Handle<String> string;
75   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
76       isolate, string,
77       Object::ToString(isolate, args.atOrUndefined(isolate, 1)));
78 
79   RETURN_RESULT_OR_FAILURE(isolate, Uri::Unescape(isolate, string));
80 }
81 
82 // ES6 section 18.2.1 eval (x)
BUILTIN(GlobalEval)83 BUILTIN(GlobalEval) {
84   HandleScope scope(isolate);
85   Handle<Object> x = args.atOrUndefined(isolate, 1);
86   Handle<JSFunction> target = args.target();
87   Handle<JSObject> target_global_proxy(target->global_proxy(), isolate);
88   if (!x->IsString()) return *x;
89   if (!Builtins::AllowDynamicFunction(isolate, target, target_global_proxy)) {
90     isolate->CountUsage(v8::Isolate::kFunctionConstructorReturnedUndefined);
91     return isolate->heap()->undefined_value();
92   }
93   Handle<JSFunction> function;
94   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
95       isolate, function, Compiler::GetFunctionFromString(
96                              handle(target->native_context(), isolate),
97                              Handle<String>::cast(x), NO_PARSE_RESTRICTION));
98   RETURN_RESULT_OR_FAILURE(
99       isolate,
100       Execution::Call(isolate, function, target_global_proxy, 0, nullptr));
101 }
102 
103 // ES6 section 18.2.2 isFinite ( number )
Generate_GlobalIsFinite(CodeStubAssembler * assembler)104 void Builtins::Generate_GlobalIsFinite(CodeStubAssembler* assembler) {
105   typedef CodeStubAssembler::Label Label;
106   typedef compiler::Node Node;
107   typedef CodeStubAssembler::Variable Variable;
108 
109   Node* context = assembler->Parameter(4);
110 
111   Label return_true(assembler), return_false(assembler);
112 
113   // We might need to loop once for ToNumber conversion.
114   Variable var_num(assembler, MachineRepresentation::kTagged);
115   Label loop(assembler, &var_num);
116   var_num.Bind(assembler->Parameter(1));
117   assembler->Goto(&loop);
118   assembler->Bind(&loop);
119   {
120     // Load the current {num} value.
121     Node* num = var_num.value();
122 
123     // Check if {num} is a Smi or a HeapObject.
124     assembler->GotoIf(assembler->TaggedIsSmi(num), &return_true);
125 
126     // Check if {num} is a HeapNumber.
127     Label if_numisheapnumber(assembler),
128         if_numisnotheapnumber(assembler, Label::kDeferred);
129     assembler->Branch(assembler->WordEqual(assembler->LoadMap(num),
130                                            assembler->HeapNumberMapConstant()),
131                       &if_numisheapnumber, &if_numisnotheapnumber);
132 
133     assembler->Bind(&if_numisheapnumber);
134     {
135       // Check if {num} contains a finite, non-NaN value.
136       Node* num_value = assembler->LoadHeapNumberValue(num);
137       assembler->BranchIfFloat64IsNaN(
138           assembler->Float64Sub(num_value, num_value), &return_false,
139           &return_true);
140     }
141 
142     assembler->Bind(&if_numisnotheapnumber);
143     {
144       // Need to convert {num} to a Number first.
145       Callable callable = CodeFactory::NonNumberToNumber(assembler->isolate());
146       var_num.Bind(assembler->CallStub(callable, context, num));
147       assembler->Goto(&loop);
148     }
149   }
150 
151   assembler->Bind(&return_true);
152   assembler->Return(assembler->BooleanConstant(true));
153 
154   assembler->Bind(&return_false);
155   assembler->Return(assembler->BooleanConstant(false));
156 }
157 
158 // ES6 section 18.2.3 isNaN ( number )
Generate_GlobalIsNaN(CodeStubAssembler * assembler)159 void Builtins::Generate_GlobalIsNaN(CodeStubAssembler* assembler) {
160   typedef CodeStubAssembler::Label Label;
161   typedef compiler::Node Node;
162   typedef CodeStubAssembler::Variable Variable;
163 
164   Node* context = assembler->Parameter(4);
165 
166   Label return_true(assembler), return_false(assembler);
167 
168   // We might need to loop once for ToNumber conversion.
169   Variable var_num(assembler, MachineRepresentation::kTagged);
170   Label loop(assembler, &var_num);
171   var_num.Bind(assembler->Parameter(1));
172   assembler->Goto(&loop);
173   assembler->Bind(&loop);
174   {
175     // Load the current {num} value.
176     Node* num = var_num.value();
177 
178     // Check if {num} is a Smi or a HeapObject.
179     assembler->GotoIf(assembler->TaggedIsSmi(num), &return_false);
180 
181     // Check if {num} is a HeapNumber.
182     Label if_numisheapnumber(assembler),
183         if_numisnotheapnumber(assembler, Label::kDeferred);
184     assembler->Branch(assembler->WordEqual(assembler->LoadMap(num),
185                                            assembler->HeapNumberMapConstant()),
186                       &if_numisheapnumber, &if_numisnotheapnumber);
187 
188     assembler->Bind(&if_numisheapnumber);
189     {
190       // Check if {num} contains a NaN.
191       Node* num_value = assembler->LoadHeapNumberValue(num);
192       assembler->BranchIfFloat64IsNaN(num_value, &return_true, &return_false);
193     }
194 
195     assembler->Bind(&if_numisnotheapnumber);
196     {
197       // Need to convert {num} to a Number first.
198       Callable callable = CodeFactory::NonNumberToNumber(assembler->isolate());
199       var_num.Bind(assembler->CallStub(callable, context, num));
200       assembler->Goto(&loop);
201     }
202   }
203 
204   assembler->Bind(&return_true);
205   assembler->Return(assembler->BooleanConstant(true));
206 
207   assembler->Bind(&return_false);
208   assembler->Return(assembler->BooleanConstant(false));
209 }
210 
211 }  // namespace internal
212 }  // namespace v8
213