OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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/asmjs/asm-typer.h" | 5 #include "src/asmjs/asm-typer.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "src/v8.h" | 10 #include "src/v8.h" |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
193 auto* sqrt = ceil; | 193 auto* sqrt = ceil; |
194 | 194 |
195 struct StandardMemberInitializer { | 195 struct StandardMemberInitializer { |
196 const char* name; | 196 const char* name; |
197 StandardMember standard_member; | 197 StandardMember standard_member; |
198 AsmType* type; | 198 AsmType* type; |
199 }; | 199 }; |
200 | 200 |
201 const StandardMemberInitializer stdlib[] = {{"Infinity", kInfinity, d}, | 201 const StandardMemberInitializer stdlib[] = {{"Infinity", kInfinity, d}, |
202 {"NaN", kNaN, d}, | 202 {"NaN", kNaN, d}, |
203 #define asm_TYPED_ARRAYS(V) \ | 203 #define ASM_TYPED_ARRAYS(V) \ |
204 V(Uint8) \ | 204 V(Uint8) \ |
205 V(Int8) \ | 205 V(Int8) \ |
206 V(Uint16) \ | 206 V(Uint16) \ |
207 V(Int16) \ | 207 V(Int16) \ |
208 V(Uint32) \ | 208 V(Uint32) \ |
209 V(Int32) \ | 209 V(Int32) \ |
210 V(Float32) \ | 210 V(Float32) \ |
211 V(Float64) | 211 V(Float64) |
212 | 212 |
213 #define asm_TYPED_ARRAY(TypeName) \ | 213 #define ASM_TYPED_ARRAY(TypeName) \ |
214 {#TypeName "Array", kNone, AsmType::TypeName##Array()}, | 214 {#TypeName "Array", kNone, AsmType::TypeName##Array()}, |
215 asm_TYPED_ARRAYS(asm_TYPED_ARRAY) | 215 ASM_TYPED_ARRAYS(ASM_TYPED_ARRAY) |
216 #undef asm_TYPED_ARRAY | 216 #undef ASM_TYPED_ARRAY |
217 }; | 217 }; |
218 for (size_t ii = 0; ii < arraysize(stdlib); ++ii) { | 218 for (size_t ii = 0; ii < arraysize(stdlib); ++ii) { |
219 stdlib_types_[stdlib[ii].name] = new (zone_) VariableInfo(stdlib[ii].type); | 219 stdlib_types_[stdlib[ii].name] = new (zone_) VariableInfo(stdlib[ii].type); |
220 stdlib_types_[stdlib[ii].name]->set_standard_member( | 220 stdlib_types_[stdlib[ii].name]->set_standard_member( |
221 stdlib[ii].standard_member); | 221 stdlib[ii].standard_member); |
222 stdlib_types_[stdlib[ii].name]->set_mutability( | 222 stdlib_types_[stdlib[ii].name]->set_mutability( |
223 VariableInfo::kImmutableGlobal); | 223 VariableInfo::kImmutableGlobal); |
224 } | 224 } |
225 | 225 |
226 const StandardMemberInitializer math[] = { | 226 const StandardMemberInitializer math[] = { |
(...skipping 1389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1616 } | 1616 } |
1617 | 1617 |
1618 return value_type; | 1618 return value_type; |
1619 } | 1619 } |
1620 | 1620 |
1621 if (auto* target_as_property = assignment->target()->AsProperty()) { | 1621 if (auto* target_as_property = assignment->target()->AsProperty()) { |
1622 AsmType* allowed_store_types; | 1622 AsmType* allowed_store_types; |
1623 RECURSE(allowed_store_types = | 1623 RECURSE(allowed_store_types = |
1624 ValidateHeapAccess(target_as_property, StoreToHeap)); | 1624 ValidateHeapAccess(target_as_property, StoreToHeap)); |
1625 | 1625 |
1626 // TODO(jpp): Change FloatishDoubleQ and FloatQDoubleQ so that they are base | 1626 if (!value_type->IsA(allowed_store_types)) { |
1627 // classes for Floatish, DoubleQ, and FloatQ. | 1627 FAIL(assignment, "Type mismatch in heap assignment."); |
1628 if (allowed_store_types == AsmType::FloatishDoubleQ()) { | |
1629 if (!value_type->IsA(AsmType::Floatish()) && | |
1630 !value_type->IsA(AsmType::DoubleQ())) { | |
1631 FAIL(assignment, "Type mismatch in heap assignment."); | |
1632 } | |
1633 } else if (allowed_store_types == AsmType::FloatQDoubleQ()) { | |
1634 if (!value_type->IsA(AsmType::FloatQ()) && | |
1635 !value_type->IsA(AsmType::DoubleQ())) { | |
1636 FAIL(assignment, "Type mismatch in heap assignment."); | |
1637 } | |
1638 } else { | |
1639 if (!value_type->IsA(allowed_store_types)) { | |
1640 FAIL(assignment, "Type mismatch in heap assignment."); | |
1641 } | |
1642 } | 1628 } |
1643 | 1629 |
1644 return value_type; | 1630 return value_type; |
1645 } | 1631 } |
1646 | 1632 |
1647 FAIL(assignment, "Invalid asm.js assignment."); | 1633 FAIL(assignment, "Invalid asm.js assignment."); |
1648 } | 1634 } |
1649 | 1635 |
1650 // 6.8.7 UnaryExpression | 1636 // 6.8.7 UnaryExpression |
1651 AsmType* AsmTyper::ValidateUnaryExpression(UnaryOperation* unop) { | 1637 AsmType* AsmTyper::ValidateUnaryExpression(UnaryOperation* unop) { |
(...skipping 635 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2287 if (as_literal == nullptr) { | 2273 if (as_literal == nullptr) { |
2288 return false; | 2274 return false; |
2289 } | 2275 } |
2290 | 2276 |
2291 if (as_literal->raw_value()->ContainsDot()) { | 2277 if (as_literal->raw_value()->ContainsDot()) { |
2292 return false; | 2278 return false; |
2293 } | 2279 } |
2294 | 2280 |
2295 return as_literal->value()->ToUint32(value); | 2281 return as_literal->value()->ToUint32(value); |
2296 } | 2282 } |
| 2283 |
| 2284 // Returns whether index is too large to access a heap with the given type. |
| 2285 bool LiteralIndexOutOfBounds(AsmType* obj_type, uint32_t index) { |
| 2286 switch (obj_type->ElementSizeInBytes()) { |
| 2287 case 1: |
| 2288 return false; |
| 2289 case 2: |
| 2290 return (index & 0x80000000u) != 0; |
| 2291 case 4: |
| 2292 return (index & 0xC0000000u) != 0; |
| 2293 case 8: |
| 2294 return (index & 0xE0000000u) != 0; |
| 2295 } |
| 2296 UNREACHABLE(); |
| 2297 return true; |
| 2298 } |
| 2299 |
2297 } // namespace | 2300 } // namespace |
2298 | 2301 |
2299 AsmType* AsmTyper::ValidateHeapAccess(Property* heap, | 2302 AsmType* AsmTyper::ValidateHeapAccess(Property* heap, |
2300 HeapAccessType access_type) { | 2303 HeapAccessType access_type) { |
2301 auto* obj = heap->obj()->AsVariableProxy(); | 2304 auto* obj = heap->obj()->AsVariableProxy(); |
2302 if (obj == nullptr) { | 2305 if (obj == nullptr) { |
2303 FAIL(heap, "Invalid heap access."); | 2306 FAIL(heap, "Invalid heap access."); |
2304 } | 2307 } |
2305 | 2308 |
2306 auto* obj_info = Lookup(obj->var()); | 2309 auto* obj_info = Lookup(obj->var()); |
2307 if (obj_info == nullptr) { | 2310 if (obj_info == nullptr) { |
2308 FAIL(heap, "Undeclared identifier in heap access."); | 2311 FAIL(heap, "Undeclared identifier in heap access."); |
2309 } | 2312 } |
2310 | 2313 |
2311 auto* obj_type = obj_info->type(); | 2314 auto* obj_type = obj_info->type(); |
2312 if (!obj_type->IsA(AsmType::Heap())) { | 2315 if (!obj_type->IsA(AsmType::Heap())) { |
2313 FAIL(heap, "Identifier does not represent a heap view."); | 2316 FAIL(heap, "Identifier does not represent a heap view."); |
2314 } | 2317 } |
2315 SetTypeOf(obj, obj_type); | 2318 SetTypeOf(obj, obj_type); |
2316 | 2319 |
2317 if (auto* key_as_literal = heap->key()->AsLiteral()) { | 2320 if (auto* key_as_literal = heap->key()->AsLiteral()) { |
2318 if (key_as_literal->raw_value()->ContainsDot()) { | 2321 if (key_as_literal->raw_value()->ContainsDot()) { |
2319 FAIL(key_as_literal, "Heap access index must be intish."); | 2322 FAIL(key_as_literal, "Heap access index must be int."); |
2320 } | 2323 } |
2321 | 2324 |
2322 uint32_t _; | 2325 uint32_t index; |
2323 if (!key_as_literal->value()->ToUint32(&_)) { | 2326 if (!key_as_literal->value()->ToUint32(&index)) { |
2324 FAIL(key_as_literal, | 2327 FAIL(key_as_literal, |
2325 "Heap access index must be a 32-bit unsigned integer."); | 2328 "Heap access index must be a 32-bit unsigned integer."); |
2326 } | 2329 } |
2327 | 2330 |
| 2331 if (LiteralIndexOutOfBounds(obj_type, index)) { |
| 2332 FAIL(key_as_literal, "Heap access index is out of bounds"); |
| 2333 } |
| 2334 |
2328 if (access_type == LoadFromHeap) { | 2335 if (access_type == LoadFromHeap) { |
2329 return obj_type->LoadType(); | 2336 return obj_type->LoadType(); |
2330 } | 2337 } |
2331 return obj_type->StoreType(); | 2338 return obj_type->StoreType(); |
2332 } | 2339 } |
2333 | 2340 |
2334 if (auto* key_as_binop = heap->key()->AsBinaryOperation()) { | 2341 if (auto* key_as_binop = heap->key()->AsBinaryOperation()) { |
2335 uint32_t shift; | 2342 uint32_t shift; |
2336 if (key_as_binop->op() == Token::SAR && | 2343 if (key_as_binop->op() == Token::SAR && |
2337 ExtractHeapAccessShift(key_as_binop->right(), &shift) && | 2344 ExtractHeapAccessShift(key_as_binop->right(), &shift) && |
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2621 return true; | 2628 return true; |
2622 } | 2629 } |
2623 | 2630 |
2624 *error_message = typer.error_message(); | 2631 *error_message = typer.error_message(); |
2625 return false; | 2632 return false; |
2626 } | 2633 } |
2627 | 2634 |
2628 } // namespace wasm | 2635 } // namespace wasm |
2629 } // namespace internal | 2636 } // namespace internal |
2630 } // namespace v8 | 2637 } // namespace v8 |
OLD | NEW |