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/builtins.h" | 5 #include "src/builtins.h" |
6 | 6 |
7 #include "src/api.h" | |
8 #include "src/api-arguments.h" | 7 #include "src/api-arguments.h" |
9 #include "src/api-natives.h" | 8 #include "src/api-natives.h" |
| 9 #include "src/api.h" |
10 #include "src/base/once.h" | 10 #include "src/base/once.h" |
11 #include "src/bootstrapper.h" | 11 #include "src/bootstrapper.h" |
12 #include "src/code-factory.h" | 12 #include "src/code-factory.h" |
13 #include "src/compiler/code-stub-assembler.h" | 13 #include "src/code-stub-assembler.h" |
14 #include "src/dateparser-inl.h" | 14 #include "src/dateparser-inl.h" |
15 #include "src/elements.h" | 15 #include "src/elements.h" |
16 #include "src/frames-inl.h" | 16 #include "src/frames-inl.h" |
17 #include "src/gdb-jit.h" | 17 #include "src/gdb-jit.h" |
18 #include "src/ic/handler-compiler.h" | 18 #include "src/ic/handler-compiler.h" |
19 #include "src/ic/ic.h" | 19 #include "src/ic/ic.h" |
20 #include "src/isolate-inl.h" | 20 #include "src/isolate-inl.h" |
21 #include "src/messages.h" | 21 #include "src/messages.h" |
22 #include "src/profiler/cpu-profiler.h" | 22 #include "src/profiler/cpu-profiler.h" |
23 #include "src/property-descriptor.h" | 23 #include "src/property-descriptor.h" |
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
345 | 345 |
346 | 346 |
347 BUILTIN(Illegal) { | 347 BUILTIN(Illegal) { |
348 UNREACHABLE(); | 348 UNREACHABLE(); |
349 return isolate->heap()->undefined_value(); // Make compiler happy. | 349 return isolate->heap()->undefined_value(); // Make compiler happy. |
350 } | 350 } |
351 | 351 |
352 | 352 |
353 BUILTIN(EmptyFunction) { return isolate->heap()->undefined_value(); } | 353 BUILTIN(EmptyFunction) { return isolate->heap()->undefined_value(); } |
354 | 354 |
355 void Builtins::Generate_ObjectHasOwnProperty( | 355 void Builtins::Generate_ObjectHasOwnProperty(CodeStubAssembler* assembler) { |
356 compiler::CodeStubAssembler* assembler) { | |
357 typedef compiler::Node Node; | 356 typedef compiler::Node Node; |
358 typedef compiler::CodeStubAssembler::Label Label; | 357 typedef CodeStubAssembler::Label Label; |
359 typedef compiler::CodeStubAssembler::Variable Variable; | 358 typedef CodeStubAssembler::Variable Variable; |
360 | 359 |
361 Node* object = assembler->Parameter(0); | 360 Node* object = assembler->Parameter(0); |
362 Node* key = assembler->Parameter(1); | 361 Node* key = assembler->Parameter(1); |
363 Node* context = assembler->Parameter(4); | 362 Node* context = assembler->Parameter(4); |
364 | 363 |
365 Label call_runtime(assembler), return_true(assembler), | 364 Label call_runtime(assembler), return_true(assembler), |
366 return_false(assembler); | 365 return_false(assembler); |
367 | 366 |
368 // Smi receivers do not have own properties. | 367 // Smi receivers do not have own properties. |
369 Label if_objectisnotsmi(assembler); | 368 Label if_objectisnotsmi(assembler); |
(...skipping 1757 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2127 HandleScope scope(isolate); | 2126 HandleScope scope(isolate); |
2128 DCHECK_EQ(2, args.length()); | 2127 DCHECK_EQ(2, args.length()); |
2129 Handle<Object> x = args.at<Object>(1); | 2128 Handle<Object> x = args.at<Object>(1); |
2130 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, x, Object::ToNumber(x)); | 2129 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, x, Object::ToNumber(x)); |
2131 return *isolate->factory()->NewHeapNumber(std::atan(x->Number())); | 2130 return *isolate->factory()->NewHeapNumber(std::atan(x->Number())); |
2132 } | 2131 } |
2133 | 2132 |
2134 namespace { | 2133 namespace { |
2135 | 2134 |
2136 void Generate_MathRoundingOperation( | 2135 void Generate_MathRoundingOperation( |
2137 compiler::CodeStubAssembler* assembler, | 2136 CodeStubAssembler* assembler, |
2138 compiler::Node* (compiler::CodeStubAssembler::*float64op)( | 2137 compiler::Node* (CodeStubAssembler::*float64op)(compiler::Node*)) { |
2139 compiler::Node*)) { | 2138 typedef CodeStubAssembler::Label Label; |
2140 typedef compiler::CodeStubAssembler::Label Label; | |
2141 typedef compiler::Node Node; | 2139 typedef compiler::Node Node; |
2142 typedef compiler::CodeStubAssembler::Variable Variable; | 2140 typedef CodeStubAssembler::Variable Variable; |
2143 | 2141 |
2144 Node* context = assembler->Parameter(4); | 2142 Node* context = assembler->Parameter(4); |
2145 | 2143 |
2146 // We might need to loop once for ToNumber conversion. | 2144 // We might need to loop once for ToNumber conversion. |
2147 Variable var_x(assembler, MachineRepresentation::kTagged); | 2145 Variable var_x(assembler, MachineRepresentation::kTagged); |
2148 Label loop(assembler, &var_x); | 2146 Label loop(assembler, &var_x); |
2149 var_x.Bind(assembler->Parameter(1)); | 2147 var_x.Bind(assembler->Parameter(1)); |
2150 assembler->Goto(&loop); | 2148 assembler->Goto(&loop); |
2151 assembler->Bind(&loop); | 2149 assembler->Bind(&loop); |
2152 { | 2150 { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2189 var_x.Bind(assembler->CallStub(callable, context, x)); | 2187 var_x.Bind(assembler->CallStub(callable, context, x)); |
2190 assembler->Goto(&loop); | 2188 assembler->Goto(&loop); |
2191 } | 2189 } |
2192 } | 2190 } |
2193 } | 2191 } |
2194 } | 2192 } |
2195 | 2193 |
2196 } // namespace | 2194 } // namespace |
2197 | 2195 |
2198 // ES6 section 20.2.2.10 Math.ceil ( x ) | 2196 // ES6 section 20.2.2.10 Math.ceil ( x ) |
2199 void Builtins::Generate_MathCeil(compiler::CodeStubAssembler* assembler) { | 2197 void Builtins::Generate_MathCeil(CodeStubAssembler* assembler) { |
2200 Generate_MathRoundingOperation(assembler, | 2198 Generate_MathRoundingOperation(assembler, &CodeStubAssembler::Float64Ceil); |
2201 &compiler::CodeStubAssembler::Float64Ceil); | |
2202 } | 2199 } |
2203 | 2200 |
2204 // ES6 section 20.2.2.11 Math.clz32 ( x ) | 2201 // ES6 section 20.2.2.11 Math.clz32 ( x ) |
2205 void Builtins::Generate_MathClz32(compiler::CodeStubAssembler* assembler) { | 2202 void Builtins::Generate_MathClz32(CodeStubAssembler* assembler) { |
2206 typedef compiler::CodeStubAssembler::Label Label; | 2203 typedef CodeStubAssembler::Label Label; |
2207 typedef compiler::Node Node; | 2204 typedef compiler::Node Node; |
2208 typedef compiler::CodeStubAssembler::Variable Variable; | 2205 typedef CodeStubAssembler::Variable Variable; |
2209 | 2206 |
2210 Node* context = assembler->Parameter(4); | 2207 Node* context = assembler->Parameter(4); |
2211 | 2208 |
2212 // Shared entry point for the clz32 operation. | 2209 // Shared entry point for the clz32 operation. |
2213 Variable var_clz32_x(assembler, MachineRepresentation::kWord32); | 2210 Variable var_clz32_x(assembler, MachineRepresentation::kWord32); |
2214 Label do_clz32(assembler); | 2211 Label do_clz32(assembler); |
2215 | 2212 |
2216 // We might need to loop once for ToNumber conversion. | 2213 // We might need to loop once for ToNumber conversion. |
2217 Variable var_x(assembler, MachineRepresentation::kTagged); | 2214 Variable var_x(assembler, MachineRepresentation::kTagged); |
2218 Label loop(assembler, &var_x); | 2215 Label loop(assembler, &var_x); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2263 assembler->Bind(&do_clz32); | 2260 assembler->Bind(&do_clz32); |
2264 { | 2261 { |
2265 Node* x_value = var_clz32_x.value(); | 2262 Node* x_value = var_clz32_x.value(); |
2266 Node* value = assembler->Word32Clz(x_value); | 2263 Node* value = assembler->Word32Clz(x_value); |
2267 Node* result = assembler->ChangeInt32ToTagged(value); | 2264 Node* result = assembler->ChangeInt32ToTagged(value); |
2268 assembler->Return(result); | 2265 assembler->Return(result); |
2269 } | 2266 } |
2270 } | 2267 } |
2271 | 2268 |
2272 // ES6 section 20.2.2.16 Math.floor ( x ) | 2269 // ES6 section 20.2.2.16 Math.floor ( x ) |
2273 void Builtins::Generate_MathFloor(compiler::CodeStubAssembler* assembler) { | 2270 void Builtins::Generate_MathFloor(CodeStubAssembler* assembler) { |
2274 Generate_MathRoundingOperation(assembler, | 2271 Generate_MathRoundingOperation(assembler, &CodeStubAssembler::Float64Floor); |
2275 &compiler::CodeStubAssembler::Float64Floor); | |
2276 } | 2272 } |
2277 | 2273 |
2278 // ES6 section 20.2.2.17 Math.fround ( x ) | 2274 // ES6 section 20.2.2.17 Math.fround ( x ) |
2279 BUILTIN(MathFround) { | 2275 BUILTIN(MathFround) { |
2280 HandleScope scope(isolate); | 2276 HandleScope scope(isolate); |
2281 DCHECK_EQ(2, args.length()); | 2277 DCHECK_EQ(2, args.length()); |
2282 Handle<Object> x = args.at<Object>(1); | 2278 Handle<Object> x = args.at<Object>(1); |
2283 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, x, Object::ToNumber(x)); | 2279 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, x, Object::ToNumber(x)); |
2284 float x32 = DoubleToFloat32(x->Number()); | 2280 float x32 = DoubleToFloat32(x->Number()); |
2285 return *isolate->factory()->NewNumber(x32); | 2281 return *isolate->factory()->NewNumber(x32); |
2286 } | 2282 } |
2287 | 2283 |
2288 // ES6 section 20.2.2.19 Math.imul ( x, y ) | 2284 // ES6 section 20.2.2.19 Math.imul ( x, y ) |
2289 BUILTIN(MathImul) { | 2285 BUILTIN(MathImul) { |
2290 HandleScope scope(isolate); | 2286 HandleScope scope(isolate); |
2291 DCHECK_EQ(3, args.length()); | 2287 DCHECK_EQ(3, args.length()); |
2292 Handle<Object> x = args.at<Object>(1); | 2288 Handle<Object> x = args.at<Object>(1); |
2293 Handle<Object> y = args.at<Object>(2); | 2289 Handle<Object> y = args.at<Object>(2); |
2294 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, x, Object::ToNumber(x)); | 2290 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, x, Object::ToNumber(x)); |
2295 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, y, Object::ToNumber(y)); | 2291 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, y, Object::ToNumber(y)); |
2296 int product = static_cast<int>(NumberToUint32(*x) * NumberToUint32(*y)); | 2292 int product = static_cast<int>(NumberToUint32(*x) * NumberToUint32(*y)); |
2297 return *isolate->factory()->NewNumberFromInt(product); | 2293 return *isolate->factory()->NewNumberFromInt(product); |
2298 } | 2294 } |
2299 | 2295 |
2300 // ES6 section 20.2.2.28 Math.round ( x ) | 2296 // ES6 section 20.2.2.28 Math.round ( x ) |
2301 void Builtins::Generate_MathRound(compiler::CodeStubAssembler* assembler) { | 2297 void Builtins::Generate_MathRound(CodeStubAssembler* assembler) { |
2302 Generate_MathRoundingOperation(assembler, | 2298 Generate_MathRoundingOperation(assembler, &CodeStubAssembler::Float64Round); |
2303 &compiler::CodeStubAssembler::Float64Round); | |
2304 } | 2299 } |
2305 | 2300 |
2306 // ES6 section 20.2.2.32 Math.sqrt ( x ) | 2301 // ES6 section 20.2.2.32 Math.sqrt ( x ) |
2307 void Builtins::Generate_MathSqrt(compiler::CodeStubAssembler* assembler) { | 2302 void Builtins::Generate_MathSqrt(CodeStubAssembler* assembler) { |
2308 using compiler::Node; | 2303 using compiler::Node; |
2309 | 2304 |
2310 Node* x = assembler->Parameter(1); | 2305 Node* x = assembler->Parameter(1); |
2311 Node* context = assembler->Parameter(4); | 2306 Node* context = assembler->Parameter(4); |
2312 Node* x_value = assembler->TruncateTaggedToFloat64(context, x); | 2307 Node* x_value = assembler->TruncateTaggedToFloat64(context, x); |
2313 Node* value = assembler->Float64Sqrt(x_value); | 2308 Node* value = assembler->Float64Sqrt(x_value); |
2314 Node* result = assembler->ChangeFloat64ToTagged(value); | 2309 Node* result = assembler->ChangeFloat64ToTagged(value); |
2315 assembler->Return(result); | 2310 assembler->Return(result); |
2316 } | 2311 } |
2317 | 2312 |
2318 // ES6 section 20.2.2.35 Math.trunc ( x ) | 2313 // ES6 section 20.2.2.35 Math.trunc ( x ) |
2319 void Builtins::Generate_MathTrunc(compiler::CodeStubAssembler* assembler) { | 2314 void Builtins::Generate_MathTrunc(CodeStubAssembler* assembler) { |
2320 Generate_MathRoundingOperation(assembler, | 2315 Generate_MathRoundingOperation(assembler, &CodeStubAssembler::Float64Trunc); |
2321 &compiler::CodeStubAssembler::Float64Trunc); | |
2322 } | 2316 } |
2323 | 2317 |
2324 // ----------------------------------------------------------------------------- | 2318 // ----------------------------------------------------------------------------- |
2325 // ES6 section 25.3 Generator Objects | 2319 // ES6 section 25.3 Generator Objects |
2326 | 2320 |
2327 namespace { | 2321 namespace { |
2328 | 2322 |
2329 void Generate_GeneratorPrototypeResume( | 2323 void Generate_GeneratorPrototypeResume( |
2330 compiler::CodeStubAssembler* assembler, | 2324 CodeStubAssembler* assembler, JSGeneratorObject::ResumeMode resume_mode, |
2331 JSGeneratorObject::ResumeMode resume_mode, char const* const method_name) { | 2325 char const* const method_name) { |
2332 typedef compiler::CodeStubAssembler::Label Label; | 2326 typedef CodeStubAssembler::Label Label; |
2333 typedef compiler::Node Node; | 2327 typedef compiler::Node Node; |
2334 | 2328 |
2335 Node* receiver = assembler->Parameter(0); | 2329 Node* receiver = assembler->Parameter(0); |
2336 Node* value = assembler->Parameter(1); | 2330 Node* value = assembler->Parameter(1); |
2337 Node* context = assembler->Parameter(4); | 2331 Node* context = assembler->Parameter(4); |
2338 Node* zero = assembler->SmiConstant(Smi::FromInt(0)); | 2332 Node* zero = assembler->SmiConstant(Smi::FromInt(0)); |
2339 | 2333 |
2340 // Check if the {receiver} is actually a JSGeneratorObject. | 2334 // Check if the {receiver} is actually a JSGeneratorObject. |
2341 Label if_receiverisincompatible(assembler, Label::kDeferred); | 2335 Label if_receiverisincompatible(assembler, Label::kDeferred); |
2342 assembler->GotoIf(assembler->WordIsSmi(receiver), &if_receiverisincompatible); | 2336 assembler->GotoIf(assembler->WordIsSmi(receiver), &if_receiverisincompatible); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2399 { | 2393 { |
2400 Node* result = | 2394 Node* result = |
2401 assembler->CallRuntime(Runtime::kThrowGeneratorRunning, context); | 2395 assembler->CallRuntime(Runtime::kThrowGeneratorRunning, context); |
2402 assembler->Return(result); // Never reached. | 2396 assembler->Return(result); // Never reached. |
2403 } | 2397 } |
2404 } | 2398 } |
2405 | 2399 |
2406 } // namespace | 2400 } // namespace |
2407 | 2401 |
2408 // ES6 section 25.3.1.2 Generator.prototype.next ( value ) | 2402 // ES6 section 25.3.1.2 Generator.prototype.next ( value ) |
2409 void Builtins::Generate_GeneratorPrototypeNext( | 2403 void Builtins::Generate_GeneratorPrototypeNext(CodeStubAssembler* assembler) { |
2410 compiler::CodeStubAssembler* assembler) { | |
2411 Generate_GeneratorPrototypeResume(assembler, JSGeneratorObject::kNext, | 2404 Generate_GeneratorPrototypeResume(assembler, JSGeneratorObject::kNext, |
2412 "[Generator].prototype.next"); | 2405 "[Generator].prototype.next"); |
2413 } | 2406 } |
2414 | 2407 |
2415 // ES6 section 25.3.1.3 Generator.prototype.return ( value ) | 2408 // ES6 section 25.3.1.3 Generator.prototype.return ( value ) |
2416 void Builtins::Generate_GeneratorPrototypeReturn( | 2409 void Builtins::Generate_GeneratorPrototypeReturn(CodeStubAssembler* assembler) { |
2417 compiler::CodeStubAssembler* assembler) { | |
2418 Generate_GeneratorPrototypeResume(assembler, JSGeneratorObject::kReturn, | 2410 Generate_GeneratorPrototypeResume(assembler, JSGeneratorObject::kReturn, |
2419 "[Generator].prototype.return"); | 2411 "[Generator].prototype.return"); |
2420 } | 2412 } |
2421 | 2413 |
2422 // ES6 section 25.3.1.4 Generator.prototype.throw ( exception ) | 2414 // ES6 section 25.3.1.4 Generator.prototype.throw ( exception ) |
2423 void Builtins::Generate_GeneratorPrototypeThrow( | 2415 void Builtins::Generate_GeneratorPrototypeThrow(CodeStubAssembler* assembler) { |
2424 compiler::CodeStubAssembler* assembler) { | |
2425 Generate_GeneratorPrototypeResume(assembler, JSGeneratorObject::kThrow, | 2416 Generate_GeneratorPrototypeResume(assembler, JSGeneratorObject::kThrow, |
2426 "[Generator].prototype.throw"); | 2417 "[Generator].prototype.throw"); |
2427 } | 2418 } |
2428 | 2419 |
2429 // ----------------------------------------------------------------------------- | 2420 // ----------------------------------------------------------------------------- |
2430 // ES6 section 26.1 The Reflect Object | 2421 // ES6 section 26.1 The Reflect Object |
2431 | 2422 |
2432 // ES6 section 26.1.3 Reflect.defineProperty | 2423 // ES6 section 26.1.3 Reflect.defineProperty |
2433 BUILTIN(ReflectDefineProperty) { | 2424 BUILTIN(ReflectDefineProperty) { |
2434 HandleScope scope(isolate); | 2425 HandleScope scope(isolate); |
(...skipping 2352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4787 // Move the code into the object heap. | 4778 // Move the code into the object heap. |
4788 CodeDesc desc; | 4779 CodeDesc desc; |
4789 masm.GetCode(&desc); | 4780 masm.GetCode(&desc); |
4790 Code::Flags flags = builtin_desc->flags; | 4781 Code::Flags flags = builtin_desc->flags; |
4791 return isolate->factory()->NewCode(desc, flags, masm.CodeObject()); | 4782 return isolate->factory()->NewCode(desc, flags, masm.CodeObject()); |
4792 } | 4783 } |
4793 | 4784 |
4794 Handle<Code> CodeStubAssemblerBuilder(Isolate* isolate, | 4785 Handle<Code> CodeStubAssemblerBuilder(Isolate* isolate, |
4795 BuiltinDesc const* builtin_desc) { | 4786 BuiltinDesc const* builtin_desc) { |
4796 Zone zone(isolate->allocator()); | 4787 Zone zone(isolate->allocator()); |
4797 compiler::CodeStubAssembler assembler(isolate, &zone, builtin_desc->argc, | 4788 CodeStubAssembler assembler(isolate, &zone, builtin_desc->argc, |
4798 builtin_desc->flags, | 4789 builtin_desc->flags, builtin_desc->s_name); |
4799 builtin_desc->s_name); | |
4800 // Generate the code/adaptor. | 4790 // Generate the code/adaptor. |
4801 typedef void (*Generator)(compiler::CodeStubAssembler*); | 4791 typedef void (*Generator)(CodeStubAssembler*); |
4802 Generator g = FUNCTION_CAST<Generator>(builtin_desc->generator); | 4792 Generator g = FUNCTION_CAST<Generator>(builtin_desc->generator); |
4803 g(&assembler); | 4793 g(&assembler); |
4804 return assembler.GenerateCode(); | 4794 return assembler.GenerateCode(); |
4805 } | 4795 } |
4806 | 4796 |
4807 } // namespace | 4797 } // namespace |
4808 | 4798 |
4809 // Define array of pointers to generators and C builtin functions. | 4799 // Define array of pointers to generators and C builtin functions. |
4810 // We do this in a sort of roundabout way so that we can do the initialization | 4800 // We do this in a sort of roundabout way so that we can do the initialization |
4811 // within the lexical scope of Builtins:: and within a context where | 4801 // within the lexical scope of Builtins:: and within a context where |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4981 BUILTIN_LIST_T(DEFINE_BUILTIN_ACCESSOR_T) | 4971 BUILTIN_LIST_T(DEFINE_BUILTIN_ACCESSOR_T) |
4982 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) | 4972 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) |
4983 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) | 4973 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) |
4984 #undef DEFINE_BUILTIN_ACCESSOR_C | 4974 #undef DEFINE_BUILTIN_ACCESSOR_C |
4985 #undef DEFINE_BUILTIN_ACCESSOR_A | 4975 #undef DEFINE_BUILTIN_ACCESSOR_A |
4986 #undef DEFINE_BUILTIN_ACCESSOR_T | 4976 #undef DEFINE_BUILTIN_ACCESSOR_T |
4987 #undef DEFINE_BUILTIN_ACCESSOR_H | 4977 #undef DEFINE_BUILTIN_ACCESSOR_H |
4988 | 4978 |
4989 } // namespace internal | 4979 } // namespace internal |
4990 } // namespace v8 | 4980 } // namespace v8 |
OLD | NEW |