OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 // This files contains runtime support implemented in JavaScript. | 5 // This files contains runtime support implemented in JavaScript. |
6 | 6 |
7 // CAUTION: Some of the functions specified in this file are called | 7 // CAUTION: Some of the functions specified in this file are called |
8 // directly from compiled code. These are the functions with names in | 8 // directly from compiled code. These are the functions with names in |
9 // ALL CAPS. The compiled code passes the first argument in 'this'. | 9 // ALL CAPS. The compiled code passes the first argument in 'this'. |
10 | 10 |
11 | 11 |
12 // The following declarations are shared with other native JS files. | 12 // The following declarations are shared with other native JS files. |
13 // They are all declared at this one spot to avoid redeclaration errors. | 13 // They are all declared at this one spot to avoid redeclaration errors. |
14 var $defaultString; | 14 var $defaultString; |
15 var $NaN; | 15 var $NaN; |
16 var $nonNumberToNumber; | 16 var $nonNumberToNumber; |
17 var $nonStringToString; | |
18 var $sameValue; | 17 var $sameValue; |
19 var $sameValueZero; | 18 var $sameValueZero; |
20 var $toInteger; | 19 var $toInteger; |
21 var $toLength; | 20 var $toLength; |
22 var $toNumber; | 21 var $toNumber; |
23 var $toPositiveInteger; | 22 var $toPositiveInteger; |
24 var $toString; | |
25 | 23 |
26 var harmony_tolength = false; | 24 var harmony_tolength = false; |
27 | 25 |
28 (function(global, utils) { | 26 (function(global, utils) { |
29 | 27 |
30 %CheckIsBootstrapping(); | 28 %CheckIsBootstrapping(); |
31 | 29 |
32 var GlobalArray = global.Array; | 30 var GlobalArray = global.Array; |
33 var GlobalBoolean = global.Boolean; | 31 var GlobalBoolean = global.Boolean; |
34 var GlobalString = global.String; | 32 var GlobalString = global.String; |
35 var isConcatSpreadableSymbol = | 33 var isConcatSpreadableSymbol = |
36 utils.ImportNow("is_concat_spreadable_symbol"); | 34 utils.ImportNow("is_concat_spreadable_symbol"); |
37 | 35 |
38 // ---------------------------------------------------------------------------- | 36 // ---------------------------------------------------------------------------- |
39 | 37 |
40 /* ----------------------------- | 38 /* ----------------------------- |
41 - - - H e l p e r s - - - | 39 - - - H e l p e r s - - - |
42 ----------------------------- | 40 ----------------------------- |
43 */ | 41 */ |
44 | 42 |
45 function APPLY_PREPARE(args) { | 43 function APPLY_PREPARE(args) { |
46 var length; | 44 var length; |
47 | 45 |
48 // First check that the receiver is callable. | 46 // First check that the receiver is callable. |
49 if (!IS_CALLABLE(this)) { | 47 if (!IS_CALLABLE(this)) { |
50 throw %make_type_error(kApplyNonFunction, %to_string_fun(this), | 48 throw %make_type_error(kApplyNonFunction, TO_STRING(this), typeof this); |
51 typeof this); | |
52 } | 49 } |
53 | 50 |
54 // First check whether length is a positive Smi and args is an | 51 // First check whether length is a positive Smi and args is an |
55 // array. This is the fast case. If this fails, we do the slow case | 52 // array. This is the fast case. If this fails, we do the slow case |
56 // that takes care of more eventualities. | 53 // that takes care of more eventualities. |
57 if (IS_ARRAY(args)) { | 54 if (IS_ARRAY(args)) { |
58 length = args.length; | 55 length = args.length; |
59 if (%_IsSmi(length) && length >= 0 && length < kSafeArgumentsLength) { | 56 if (%_IsSmi(length) && length >= 0 && length < kSafeArgumentsLength) { |
60 return length; | 57 return length; |
61 } | 58 } |
(...skipping 15 matching lines...) Expand all Loading... |
77 // stack. It is guaranteed to be a small integer at this point. | 74 // stack. It is guaranteed to be a small integer at this point. |
78 return length; | 75 return length; |
79 } | 76 } |
80 | 77 |
81 | 78 |
82 function REFLECT_APPLY_PREPARE(args) { | 79 function REFLECT_APPLY_PREPARE(args) { |
83 var length; | 80 var length; |
84 | 81 |
85 // First check that the receiver is callable. | 82 // First check that the receiver is callable. |
86 if (!IS_CALLABLE(this)) { | 83 if (!IS_CALLABLE(this)) { |
87 throw %make_type_error(kApplyNonFunction, %to_string_fun(this), | 84 throw %make_type_error(kApplyNonFunction, TO_STRING(this), typeof this); |
88 typeof this); | |
89 } | 85 } |
90 | 86 |
91 // First check whether length is a positive Smi and args is an | 87 // First check whether length is a positive Smi and args is an |
92 // array. This is the fast case. If this fails, we do the slow case | 88 // array. This is the fast case. If this fails, we do the slow case |
93 // that takes care of more eventualities. | 89 // that takes care of more eventualities. |
94 if (IS_ARRAY(args)) { | 90 if (IS_ARRAY(args)) { |
95 length = args.length; | 91 length = args.length; |
96 if (%_IsSmi(length) && length >= 0 && length < kSafeArgumentsLength) { | 92 if (%_IsSmi(length) && length >= 0 && length < kSafeArgumentsLength) { |
97 return length; | 93 return length; |
98 } | 94 } |
(...skipping 28 matching lines...) Expand all Loading... |
127 if (IS_ARRAY(args)) { | 123 if (IS_ARRAY(args)) { |
128 length = args.length; | 124 length = args.length; |
129 if (%_IsSmi(length) && length >= 0 && length < kSafeArgumentsLength && | 125 if (%_IsSmi(length) && length >= 0 && length < kSafeArgumentsLength && |
130 ctorOk && newTargetOk) { | 126 ctorOk && newTargetOk) { |
131 return length; | 127 return length; |
132 } | 128 } |
133 } | 129 } |
134 | 130 |
135 if (!ctorOk) { | 131 if (!ctorOk) { |
136 if (!IS_CALLABLE(this)) { | 132 if (!IS_CALLABLE(this)) { |
137 throw %make_type_error(kCalledNonCallable, %to_string_fun(this)); | 133 throw %make_type_error(kCalledNonCallable, TO_STRING(this)); |
138 } else { | 134 } else { |
139 throw %make_type_error(kNotConstructor, %to_string_fun(this)); | 135 throw %make_type_error(kNotConstructor, TO_STRING(this)); |
140 } | 136 } |
141 } | 137 } |
142 | 138 |
143 if (!newTargetOk) { | 139 if (!newTargetOk) { |
144 if (!IS_CALLABLE(newTarget)) { | 140 if (!IS_CALLABLE(newTarget)) { |
145 throw %make_type_error(kCalledNonCallable, %to_string_fun(newTarget)); | 141 throw %make_type_error(kCalledNonCallable, TO_STRING(newTarget)); |
146 } else { | 142 } else { |
147 throw %make_type_error(kNotConstructor, %to_string_fun(newTarget)); | 143 throw %make_type_error(kNotConstructor, TO_STRING(newTarget)); |
148 } | 144 } |
149 } | 145 } |
150 | 146 |
151 if (!IS_SPEC_OBJECT(args)) { | 147 if (!IS_SPEC_OBJECT(args)) { |
152 throw %make_type_error(kWrongArgs, "Reflect.construct"); | 148 throw %make_type_error(kWrongArgs, "Reflect.construct"); |
153 } | 149 } |
154 | 150 |
155 length = %to_length_fun(args.length); | 151 length = %to_length_fun(args.length); |
156 | 152 |
157 // We can handle any number of apply arguments if the stack is | 153 // We can handle any number of apply arguments if the stack is |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
213 // ECMA-262, section 9.8, page 35. | 209 // ECMA-262, section 9.8, page 35. |
214 function ToString(x) { | 210 function ToString(x) { |
215 if (IS_STRING(x)) return x; | 211 if (IS_STRING(x)) return x; |
216 if (IS_NUMBER(x)) return %_NumberToString(x); | 212 if (IS_NUMBER(x)) return %_NumberToString(x); |
217 if (IS_BOOLEAN(x)) return x ? 'true' : 'false'; | 213 if (IS_BOOLEAN(x)) return x ? 'true' : 'false'; |
218 if (IS_UNDEFINED(x)) return 'undefined'; | 214 if (IS_UNDEFINED(x)) return 'undefined'; |
219 // Types that can't be converted to string are caught in DefaultString. | 215 // Types that can't be converted to string are caught in DefaultString. |
220 return (IS_NULL(x)) ? 'null' : ToString(DefaultString(x)); | 216 return (IS_NULL(x)) ? 'null' : ToString(DefaultString(x)); |
221 } | 217 } |
222 | 218 |
223 function NonStringToString(x) { | |
224 if (IS_NUMBER(x)) return %_NumberToString(x); | |
225 if (IS_BOOLEAN(x)) return x ? 'true' : 'false'; | |
226 if (IS_UNDEFINED(x)) return 'undefined'; | |
227 // Types that can't be converted to string are caught in DefaultString. | |
228 return (IS_NULL(x)) ? 'null' : ToString(DefaultString(x)); | |
229 } | |
230 | |
231 | 219 |
232 // ECMA-262, section 9.4, page 34. | 220 // ECMA-262, section 9.4, page 34. |
233 function ToInteger(x) { | 221 function ToInteger(x) { |
234 if (%_IsSmi(x)) return x; | 222 if (%_IsSmi(x)) return x; |
235 return %NumberToInteger(ToNumber(x)); | 223 return %NumberToInteger(ToNumber(x)); |
236 } | 224 } |
237 | 225 |
238 | 226 |
239 // ES6, draft 08-24-14, section 7.1.15 | 227 // ES6, draft 08-24-14, section 7.1.15 |
240 function ToLength(arg) { | 228 function ToLength(arg) { |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
353 // that is cloned when running the code. It is essential that the | 341 // that is cloned when running the code. It is essential that the |
354 // boilerplate gets the right prototype. | 342 // boilerplate gets the right prototype. |
355 %FunctionSetPrototype(GlobalArray, new GlobalArray(0)); | 343 %FunctionSetPrototype(GlobalArray, new GlobalArray(0)); |
356 | 344 |
357 // ---------------------------------------------------------------------------- | 345 // ---------------------------------------------------------------------------- |
358 // Exports | 346 // Exports |
359 | 347 |
360 $defaultString = DefaultString; | 348 $defaultString = DefaultString; |
361 $NaN = %GetRootNaN(); | 349 $NaN = %GetRootNaN(); |
362 $nonNumberToNumber = NonNumberToNumber; | 350 $nonNumberToNumber = NonNumberToNumber; |
363 $nonStringToString = NonStringToString; | |
364 $sameValue = SameValue; | 351 $sameValue = SameValue; |
365 $sameValueZero = SameValueZero; | 352 $sameValueZero = SameValueZero; |
366 $toInteger = ToInteger; | 353 $toInteger = ToInteger; |
367 $toLength = ToLength; | 354 $toLength = ToLength; |
368 $toNumber = ToNumber; | 355 $toNumber = ToNumber; |
369 $toPositiveInteger = ToPositiveInteger; | 356 $toPositiveInteger = ToPositiveInteger; |
370 $toString = ToString; | |
371 | 357 |
372 %InstallToContext([ | 358 %InstallToContext([ |
373 "apply_prepare_builtin", APPLY_PREPARE, | 359 "apply_prepare_builtin", APPLY_PREPARE, |
374 "concat_iterable_to_array_builtin", CONCAT_ITERABLE_TO_ARRAY, | 360 "concat_iterable_to_array_builtin", CONCAT_ITERABLE_TO_ARRAY, |
375 "reflect_apply_prepare_builtin", REFLECT_APPLY_PREPARE, | 361 "reflect_apply_prepare_builtin", REFLECT_APPLY_PREPARE, |
376 "reflect_construct_prepare_builtin", REFLECT_CONSTRUCT_PREPARE, | 362 "reflect_construct_prepare_builtin", REFLECT_CONSTRUCT_PREPARE, |
377 ]); | 363 ]); |
378 | 364 |
379 %InstallToContext([ | 365 %InstallToContext([ |
380 "concat_iterable_to_array", ConcatIterableToArray, | 366 "concat_iterable_to_array", ConcatIterableToArray, |
381 "non_number_to_number", NonNumberToNumber, | 367 "non_number_to_number", NonNumberToNumber, |
382 "non_string_to_string", NonStringToString, | |
383 "to_integer_fun", ToInteger, | 368 "to_integer_fun", ToInteger, |
384 "to_length_fun", ToLength, | 369 "to_length_fun", ToLength, |
385 "to_number_fun", ToNumber, | 370 "to_number_fun", ToNumber, |
386 "to_string_fun", ToString, | |
387 ]); | 371 ]); |
388 | 372 |
389 utils.Export(function(to) { | 373 utils.Export(function(to) { |
390 to.ToBoolean = ToBoolean; | 374 to.ToBoolean = ToBoolean; |
391 to.ToLength = ToLength; | 375 to.ToLength = ToLength; |
392 to.ToNumber = ToNumber; | 376 to.ToNumber = ToNumber; |
393 to.ToString = ToString; | 377 to.ToString = ToString; |
394 }); | 378 }); |
395 | 379 |
396 }) | 380 }) |
OLD | NEW |