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