Index: src/builtins.cc |
diff --git a/src/builtins.cc b/src/builtins.cc |
index e05a4dd45a98a38c8fc11e8f95f4ca1685a769cd..03292910729ccd3adeeab1c3ead90e489e9853ba 100644 |
--- a/src/builtins.cc |
+++ b/src/builtins.cc |
@@ -9,6 +9,7 @@ |
#include "src/arguments.h" |
#include "src/base/once.h" |
#include "src/bootstrapper.h" |
+#include "src/compiler/code-stub-assembler.h" |
#include "src/dateparser-inl.h" |
#include "src/elements.h" |
#include "src/frames-inl.h" |
@@ -4170,6 +4171,74 @@ void Builtins::Generate_StackCheck(MacroAssembler* masm) { |
} |
+void Builtins::Generate_AtomicsLoadCheck(MacroAssembler* masm) { |
+ using namespace compiler; |
+ Isolate* isolate = masm->isolate(); |
+ Zone zone; |
+ CodeStubAssembler a(isolate, &zone, 2, Code::ComputeFlags(Code::STUB), |
+ "AtomicsLoadCheck"); |
+ |
+ Node* param0 = a.Parameter(0); |
+ |
+ // Check if param0 is a heap object. |
+ CodeStubAssembler::Label is_heap_object, not_heap_object; |
+ a.Branch(a.IsHeapObject(param0), &is_heap_object, ¬_heap_object); |
+ a.Bind(¬_heap_object); |
+ a.TailCallRuntime(Runtime::kThrowNotIntegerSharedTypedArrayError, param0); |
+ a.Bind(&is_heap_object); |
+ |
+ // Check if param0's instance type is JSTypedArray. |
+ CodeStubAssembler::Label is_typed_array, not_typed_array; |
+ a.Branch( |
+ a.WordEqual(a.InstanceType(param0), a.Int32Constant(JS_TYPED_ARRAY_TYPE)), |
+ &is_typed_array, ¬_typed_array); |
+ a.Bind(¬_typed_array); |
+ a.TailCallRuntime(Runtime::kThrowNotIntegerSharedTypedArrayError, param0); |
+ a.Bind(&is_typed_array); |
+ |
+ // Check if param0's JSArrayBuffer is shared. |
+ CodeStubAssembler::Label is_shared, not_shared; |
+ Node* is_buffer_shared = a.BitFieldValue<JSArrayBuffer::IsShared>( |
+ a.LoadObjectField(a.LoadObjectField(param0, JSTypedArray::kBufferOffset), |
+ JSArrayBuffer::kBitFieldOffset)); |
+ a.Branch(is_buffer_shared, &is_shared, ¬_shared); |
+ a.Bind(¬_shared); |
+ a.TailCallRuntime(Runtime::kThrowNotIntegerSharedTypedArrayError, param0); |
+ a.Bind(&is_shared); |
+ |
+ // Check if param0's JSTypedArray element type is float32 or float64. |
+ CodeStubAssembler::Label is_float, not_float; |
+ Node* elements_instance_type = |
+ a.InstanceType(a.LoadObjectField(param0, JSObject::kElementsOffset)); |
+ a.Branch(a.WordOr(a.WordEqual(elements_instance_type, |
+ a.Int32Constant(FIXED_FLOAT32_ARRAY_TYPE)), |
+ a.WordEqual(elements_instance_type, |
+ a.Int32Constant(FIXED_FLOAT64_ARRAY_TYPE))), |
+ &is_float, ¬_float); |
+ a.Bind(&is_float); |
+ a.TailCallRuntime(Runtime::kThrowNotIntegerSharedTypedArrayError, param0); |
+ a.Bind(¬_float); |
+ |
+ // Check if the index is in bounds. If not, return undefined. |
+ CodeStubAssembler::Label in_bounds, not_in_bounds; |
+ Node* param1_int = |
+ a.SmiUntag(a.CallRuntime(Runtime::kToInteger, a.Parameter(1))); |
Jarin
2016/02/08 10:25:04
How do you know that ToInteger returns a Smi? You
|
+ // TODO(binji): is length always a smi? |
+ Node* array_length = |
+ a.SmiUntag(a.LoadObjectField(param0, JSTypedArray::kLengthOffset)); |
Jarin
2016/02/08 10:25:04
Same here.
|
+ a.Branch(a.WordOr(a.Int32LessThan(param1_int, a.Int32Constant(0)), |
+ a.Int32GreaterThanOrEqual(param1_int, array_length)), |
+ ¬_in_bounds, &in_bounds); |
+ a.Bind(¬_in_bounds); |
+ a.Return(a.UndefinedConstant()); |
+ a.Bind(&in_bounds); |
+ |
+ a.Return(a.SmiTag(a.Int32Constant(42))); |
+ |
+ masm->Jump(a.GenerateCode(), RelocInfo::CODE_TARGET); |
+} |
+ |
+ |
#define DEFINE_BUILTIN_ACCESSOR_C(name, ignore) \ |
Handle<Code> Builtins::name() { \ |
Code** code_address = \ |