| 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" | 7 #include "src/api.h" | 
| 8 #include "src/api-arguments.h" | 8 #include "src/api-arguments.h" | 
| 9 #include "src/api-natives.h" | 9 #include "src/api-natives.h" | 
| 10 #include "src/base/once.h" | 10 #include "src/base/once.h" | 
| (...skipping 4147 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 4158 // ES6 19.1.3.6 Object.prototype.toString | 4158 // ES6 19.1.3.6 Object.prototype.toString | 
| 4159 BUILTIN(ObjectProtoToString) { | 4159 BUILTIN(ObjectProtoToString) { | 
| 4160   HandleScope scope(isolate); | 4160   HandleScope scope(isolate); | 
| 4161   Handle<Object> object = args.at<Object>(0); | 4161   Handle<Object> object = args.at<Object>(0); | 
| 4162   Handle<String> result; | 4162   Handle<String> result; | 
| 4163   ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 4163   ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 
| 4164       isolate, result, Object::ObjectProtoToString(isolate, object)); | 4164       isolate, result, Object::ObjectProtoToString(isolate, object)); | 
| 4165   return *result; | 4165   return *result; | 
| 4166 } | 4166 } | 
| 4167 | 4167 | 
|  | 4168 // ----------------------------------------------------------------------------- | 
|  | 4169 // ES6 section 21.1 String Objects | 
|  | 4170 | 
|  | 4171 // ES6 section 21.1.3.1 String.prototype.charAt ( pos ) | 
|  | 4172 void Builtins::Generate_StringPrototypeCharAt( | 
|  | 4173     compiler::CodeStubAssembler* assembler) { | 
|  | 4174   typedef compiler::CodeStubAssembler::Label Label; | 
|  | 4175   typedef compiler::Node Node; | 
|  | 4176   typedef compiler::CodeStubAssembler::Variable Variable; | 
|  | 4177 | 
|  | 4178   Node* receiver = assembler->Parameter(0); | 
|  | 4179   Node* position = assembler->Parameter(1); | 
|  | 4180   Node* context = assembler->Parameter(4); | 
|  | 4181 | 
|  | 4182   // Check that {receiver} is coercible to Object and convert it to a String. | 
|  | 4183   receiver = | 
|  | 4184       assembler->ToThisString(context, receiver, "String.prototype.charAt"); | 
|  | 4185 | 
|  | 4186   // Convert the {position} to a Smi and check that it's in bounds of the | 
|  | 4187   // {receiver}. | 
|  | 4188   // TODO(bmeurer): Find an abstraction for this! | 
|  | 4189   { | 
|  | 4190     // Check if the {position} is already a Smi. | 
|  | 4191     Variable var_position(assembler, MachineRepresentation::kTagged); | 
|  | 4192     var_position.Bind(position); | 
|  | 4193     Label if_positionissmi(assembler), | 
|  | 4194         if_positionisnotsmi(assembler, Label::kDeferred); | 
|  | 4195     assembler->Branch(assembler->WordIsSmi(position), &if_positionissmi, | 
|  | 4196                       &if_positionisnotsmi); | 
|  | 4197     assembler->Bind(&if_positionisnotsmi); | 
|  | 4198     { | 
|  | 4199       // Convert the {position} to an Integer via the ToIntegerStub. | 
|  | 4200       Callable callable = CodeFactory::ToInteger(assembler->isolate()); | 
|  | 4201       Node* index = assembler->CallStub(callable, context, position); | 
|  | 4202 | 
|  | 4203       // Check if the resulting {index} is now a Smi. | 
|  | 4204       Label if_indexissmi(assembler, Label::kDeferred), | 
|  | 4205           if_indexisnotsmi(assembler, Label::kDeferred); | 
|  | 4206       assembler->Branch(assembler->WordIsSmi(index), &if_indexissmi, | 
|  | 4207                         &if_indexisnotsmi); | 
|  | 4208 | 
|  | 4209       assembler->Bind(&if_indexissmi); | 
|  | 4210       { | 
|  | 4211         var_position.Bind(index); | 
|  | 4212         assembler->Goto(&if_positionissmi); | 
|  | 4213       } | 
|  | 4214 | 
|  | 4215       assembler->Bind(&if_indexisnotsmi); | 
|  | 4216       { | 
|  | 4217         // The ToIntegerStub canonicalizes everything in Smi range to Smi | 
|  | 4218         // representation, so any HeapNumber returned is not in Smi range. | 
|  | 4219         // The only exception here is -0.0, which we treat as 0. | 
|  | 4220         Node* index_value = assembler->LoadHeapNumberValue(index); | 
|  | 4221         Label if_indexiszero(assembler, Label::kDeferred), | 
|  | 4222             if_indexisnotzero(assembler, Label::kDeferred); | 
|  | 4223         assembler->Branch(assembler->Float64Equal( | 
|  | 4224                               index_value, assembler->Float64Constant(0.0)), | 
|  | 4225                           &if_indexiszero, &if_indexisnotzero); | 
|  | 4226 | 
|  | 4227         assembler->Bind(&if_indexiszero); | 
|  | 4228         { | 
|  | 4229           var_position.Bind(assembler->SmiConstant(Smi::FromInt(0))); | 
|  | 4230           assembler->Goto(&if_positionissmi); | 
|  | 4231         } | 
|  | 4232 | 
|  | 4233         assembler->Bind(&if_indexisnotzero); | 
|  | 4234         { | 
|  | 4235           // The {index} is some other integral Number, that is definitely | 
|  | 4236           // neither -0.0 nor in Smi range. | 
|  | 4237           assembler->Return(assembler->EmptyStringConstant()); | 
|  | 4238         } | 
|  | 4239       } | 
|  | 4240     } | 
|  | 4241     assembler->Bind(&if_positionissmi); | 
|  | 4242     position = var_position.value(); | 
|  | 4243 | 
|  | 4244     // Determine the actual length of the {receiver} String. | 
|  | 4245     Node* receiver_length = | 
|  | 4246         assembler->LoadObjectField(receiver, String::kLengthOffset); | 
|  | 4247 | 
|  | 4248     // Return "" if the Smi {position} is outside the bounds of the {receiver}. | 
|  | 4249     Label if_positioninbounds(assembler), | 
|  | 4250         if_positionnotinbounds(assembler, Label::kDeferred); | 
|  | 4251     assembler->Branch(assembler->SmiAboveOrEqual(position, receiver_length), | 
|  | 4252                       &if_positionnotinbounds, &if_positioninbounds); | 
|  | 4253     assembler->Bind(&if_positionnotinbounds); | 
|  | 4254     assembler->Return(assembler->EmptyStringConstant()); | 
|  | 4255     assembler->Bind(&if_positioninbounds); | 
|  | 4256   } | 
|  | 4257 | 
|  | 4258   // Load the character code at the {position} from the {receiver}. | 
|  | 4259   Node* code = assembler->StringCharCodeAt(receiver, position); | 
|  | 4260 | 
|  | 4261   // And return the single character string with only that {code}. | 
|  | 4262   Node* result = assembler->StringFromCharCode(code); | 
|  | 4263   assembler->Return(result); | 
|  | 4264 } | 
|  | 4265 | 
|  | 4266 // ES6 section 21.1.3.2 String.prototype.charCodeAt ( pos ) | 
|  | 4267 void Builtins::Generate_StringPrototypeCharCodeAt( | 
|  | 4268     compiler::CodeStubAssembler* assembler) { | 
|  | 4269   typedef compiler::CodeStubAssembler::Label Label; | 
|  | 4270   typedef compiler::Node Node; | 
|  | 4271   typedef compiler::CodeStubAssembler::Variable Variable; | 
|  | 4272 | 
|  | 4273   Node* receiver = assembler->Parameter(0); | 
|  | 4274   Node* position = assembler->Parameter(1); | 
|  | 4275   Node* context = assembler->Parameter(4); | 
|  | 4276 | 
|  | 4277   // Check that {receiver} is coercible to Object and convert it to a String. | 
|  | 4278   receiver = | 
|  | 4279       assembler->ToThisString(context, receiver, "String.prototype.charCodeAt"); | 
|  | 4280 | 
|  | 4281   // Convert the {position} to a Smi and check that it's in bounds of the | 
|  | 4282   // {receiver}. | 
|  | 4283   // TODO(bmeurer): Find an abstraction for this! | 
|  | 4284   { | 
|  | 4285     // Check if the {position} is already a Smi. | 
|  | 4286     Variable var_position(assembler, MachineRepresentation::kTagged); | 
|  | 4287     var_position.Bind(position); | 
|  | 4288     Label if_positionissmi(assembler), | 
|  | 4289         if_positionisnotsmi(assembler, Label::kDeferred); | 
|  | 4290     assembler->Branch(assembler->WordIsSmi(position), &if_positionissmi, | 
|  | 4291                       &if_positionisnotsmi); | 
|  | 4292     assembler->Bind(&if_positionisnotsmi); | 
|  | 4293     { | 
|  | 4294       // Convert the {position} to an Integer via the ToIntegerStub. | 
|  | 4295       Callable callable = CodeFactory::ToInteger(assembler->isolate()); | 
|  | 4296       Node* index = assembler->CallStub(callable, context, position); | 
|  | 4297 | 
|  | 4298       // Check if the resulting {index} is now a Smi. | 
|  | 4299       Label if_indexissmi(assembler, Label::kDeferred), | 
|  | 4300           if_indexisnotsmi(assembler, Label::kDeferred); | 
|  | 4301       assembler->Branch(assembler->WordIsSmi(index), &if_indexissmi, | 
|  | 4302                         &if_indexisnotsmi); | 
|  | 4303 | 
|  | 4304       assembler->Bind(&if_indexissmi); | 
|  | 4305       { | 
|  | 4306         var_position.Bind(index); | 
|  | 4307         assembler->Goto(&if_positionissmi); | 
|  | 4308       } | 
|  | 4309 | 
|  | 4310       assembler->Bind(&if_indexisnotsmi); | 
|  | 4311       { | 
|  | 4312         // The ToIntegerStub canonicalizes everything in Smi range to Smi | 
|  | 4313         // representation, so any HeapNumber returned is not in Smi range. | 
|  | 4314         // The only exception here is -0.0, which we treat as 0. | 
|  | 4315         Node* index_value = assembler->LoadHeapNumberValue(index); | 
|  | 4316         Label if_indexiszero(assembler, Label::kDeferred), | 
|  | 4317             if_indexisnotzero(assembler, Label::kDeferred); | 
|  | 4318         assembler->Branch(assembler->Float64Equal( | 
|  | 4319                               index_value, assembler->Float64Constant(0.0)), | 
|  | 4320                           &if_indexiszero, &if_indexisnotzero); | 
|  | 4321 | 
|  | 4322         assembler->Bind(&if_indexiszero); | 
|  | 4323         { | 
|  | 4324           var_position.Bind(assembler->SmiConstant(Smi::FromInt(0))); | 
|  | 4325           assembler->Goto(&if_positionissmi); | 
|  | 4326         } | 
|  | 4327 | 
|  | 4328         assembler->Bind(&if_indexisnotzero); | 
|  | 4329         { | 
|  | 4330           // The {index} is some other integral Number, that is definitely | 
|  | 4331           // neither -0.0 nor in Smi range. | 
|  | 4332           assembler->Return(assembler->NaNConstant()); | 
|  | 4333         } | 
|  | 4334       } | 
|  | 4335     } | 
|  | 4336     assembler->Bind(&if_positionissmi); | 
|  | 4337     position = var_position.value(); | 
|  | 4338 | 
|  | 4339     // Determine the actual length of the {receiver} String. | 
|  | 4340     Node* receiver_length = | 
|  | 4341         assembler->LoadObjectField(receiver, String::kLengthOffset); | 
|  | 4342 | 
|  | 4343     // Return NaN if the Smi {position} is outside the bounds of the {receiver}. | 
|  | 4344     Label if_positioninbounds(assembler), | 
|  | 4345         if_positionnotinbounds(assembler, Label::kDeferred); | 
|  | 4346     assembler->Branch(assembler->SmiAboveOrEqual(position, receiver_length), | 
|  | 4347                       &if_positionnotinbounds, &if_positioninbounds); | 
|  | 4348     assembler->Bind(&if_positionnotinbounds); | 
|  | 4349     assembler->Return(assembler->NaNConstant()); | 
|  | 4350     assembler->Bind(&if_positioninbounds); | 
|  | 4351   } | 
|  | 4352 | 
|  | 4353   // Load the character at the {position} from the {receiver}. | 
|  | 4354   Node* value = assembler->StringCharCodeAt(receiver, position); | 
|  | 4355   Node* result = assembler->SmiFromWord32(value); | 
|  | 4356   assembler->Return(result); | 
|  | 4357 } | 
|  | 4358 | 
|  | 4359 // ----------------------------------------------------------------------------- | 
|  | 4360 // ES6 section 21.1 ArrayBuffer Objects | 
| 4168 | 4361 | 
| 4169 // ES6 section 24.1.2.1 ArrayBuffer ( length ) for the [[Call]] case. | 4362 // ES6 section 24.1.2.1 ArrayBuffer ( length ) for the [[Call]] case. | 
| 4170 BUILTIN(ArrayBufferConstructor) { | 4363 BUILTIN(ArrayBufferConstructor) { | 
| 4171   HandleScope scope(isolate); | 4364   HandleScope scope(isolate); | 
| 4172   Handle<JSFunction> target = args.target<JSFunction>(); | 4365   Handle<JSFunction> target = args.target<JSFunction>(); | 
| 4173   DCHECK(*target == target->native_context()->array_buffer_fun() || | 4366   DCHECK(*target == target->native_context()->array_buffer_fun() || | 
| 4174          *target == target->native_context()->shared_array_buffer_fun()); | 4367          *target == target->native_context()->shared_array_buffer_fun()); | 
| 4175   THROW_NEW_ERROR_RETURN_FAILURE( | 4368   THROW_NEW_ERROR_RETURN_FAILURE( | 
| 4176       isolate, NewTypeError(MessageTemplate::kConstructorNotFunction, | 4369       isolate, NewTypeError(MessageTemplate::kConstructorNotFunction, | 
| 4177                             handle(target->shared()->name(), isolate))); | 4370                             handle(target->shared()->name(), isolate))); | 
| (...skipping 773 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 4951 BUILTIN_LIST_T(DEFINE_BUILTIN_ACCESSOR_T) | 5144 BUILTIN_LIST_T(DEFINE_BUILTIN_ACCESSOR_T) | 
| 4952 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) | 5145 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) | 
| 4953 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) | 5146 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) | 
| 4954 #undef DEFINE_BUILTIN_ACCESSOR_C | 5147 #undef DEFINE_BUILTIN_ACCESSOR_C | 
| 4955 #undef DEFINE_BUILTIN_ACCESSOR_A | 5148 #undef DEFINE_BUILTIN_ACCESSOR_A | 
| 4956 #undef DEFINE_BUILTIN_ACCESSOR_T | 5149 #undef DEFINE_BUILTIN_ACCESSOR_T | 
| 4957 #undef DEFINE_BUILTIN_ACCESSOR_H | 5150 #undef DEFINE_BUILTIN_ACCESSOR_H | 
| 4958 | 5151 | 
| 4959 }  // namespace internal | 5152 }  // namespace internal | 
| 4960 }  // namespace v8 | 5153 }  // namespace v8 | 
| OLD | NEW | 
|---|