mirror of
				https://github.com/tc39/test262.git
				synced 2025-10-28 10:13:55 +01:00 
			
		
		
		
	* [javascriptcore-test262-automation] changes from git@github.com:WebKit/webkit.git at sha 949e26452cfa153a7f4afe593da97e2fe9e1b706 on Tue Jul 03 2018 14:35:15 GMT-0400 (Eastern Daylight Time)
		
			
				
	
	
		
			131 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			131 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| import Builder from '../Builder.js';
 | |
| import * as assert from '../assert.js';
 | |
| import * as LLB from '../LowLevelBinary.js';
 | |
| import * as WASM from '../WASM.js';
 | |
| import * as util from '../utilities.js';
 | |
| 
 | |
| const verbose = false;
 | |
| 
 | |
| const pageSize = 64 * 1024;
 | |
| const fourGiB = pageSize * 65536;
 | |
| const initial = 64;
 | |
| const maximum = 128;
 | |
| 
 | |
| // When using fast memories, we allocate a redzone after the 4GiB huge
 | |
| // allocation. This redzone is used to trap reg+imm accesses which exceed
 | |
| // 32-bits. Anything past 4GiB must trap, but we cannot know statically that it
 | |
| // will.
 | |
| 
 | |
| const offsets = [
 | |
|     0,
 | |
|     1,
 | |
|     2,
 | |
|     1024,
 | |
|     pageSize,
 | |
|     pageSize + pageSize / 2,
 | |
|     pageSize * 8,
 | |
|     pageSize * 16,
 | |
|     pageSize * 128,
 | |
|     pageSize * 512,
 | |
|     fourGiB / 4 - 4,
 | |
|     fourGiB / 4 - 3,
 | |
|     fourGiB / 4 - 2,
 | |
|     fourGiB / 4 - 1,
 | |
|     fourGiB / 4,
 | |
|     fourGiB / 4 + 1,
 | |
|     fourGiB / 4 + 2,
 | |
|     fourGiB / 4 + 3,
 | |
|     fourGiB / 4 + 4,
 | |
|     fourGiB / 2 - 4,
 | |
|     fourGiB / 2 - 3,
 | |
|     fourGiB / 2 - 2,
 | |
|     fourGiB / 2 - 1,
 | |
|     fourGiB / 2,
 | |
|     fourGiB / 2 + 1,
 | |
|     fourGiB / 2 + 2,
 | |
|     fourGiB / 2 + 3,
 | |
|     fourGiB / 2 + 4,
 | |
|     (fourGiB / 4) * 3,
 | |
|     fourGiB - 4,
 | |
|     fourGiB - 3,
 | |
|     fourGiB - 2,
 | |
|     fourGiB - 1,
 | |
| ];
 | |
| 
 | |
| for (let memoryDeclaration of [{ initial: initial }, { initial: initial, maximum: maximum }]) {
 | |
|     fullGC();
 | |
| 
 | |
|     // Re-use a single memory so tests are more likely to get a fast memory.
 | |
|     const memory = new WebAssembly.Memory(memoryDeclaration);
 | |
|     if (verbose)
 | |
|         print(WebAssemblyMemoryMode(memory));
 | |
|     const buf = new Uint8Array(memory.buffer);
 | |
| 
 | |
|     // Enumerate all memory access types.
 | |
|     for (const op of WASM.opcodes("memory")) {
 | |
|         const info = WASM.memoryAccessInfo(op);
 | |
| 
 | |
|         // The accesses should fault even if only the last byte is off the end.
 | |
|         let wiggles = [0];
 | |
|         for (let wiggle = 0; wiggle !== info.width / 8; ++wiggle)
 | |
|             wiggles.push(wiggle);
 | |
| 
 | |
|         let builder = (new Builder())
 | |
|             .Type().End()
 | |
|             .Import().Memory("imp", "memory", memoryDeclaration).End()
 | |
|             .Function().End()
 | |
|             .Export();
 | |
| 
 | |
|         for (let offset of offsets)
 | |
|             switch (info.type) {
 | |
|             case "load": builder = builder.Function("get_" + offset); break;
 | |
|             case "store": builder = builder.Function("set_" + offset); break;
 | |
|             default: throw new Error(`Implementation problem: unknown memory access type ${info.type}`);
 | |
|             }
 | |
| 
 | |
|         builder = builder.End().Code();
 | |
| 
 | |
|         const align = 0; // No need to be precise, it's just a hint.
 | |
|         const constInstr = util.toJavaScriptName(WASM.constForValueType(info.valueType));
 | |
|         const instr = util.toJavaScriptName(op.name);
 | |
|         for (let offset of offsets)
 | |
|             switch (info.type) {
 | |
|             case "load":
 | |
|                 builder = builder.Function("get_" + offset, { params: ["i32"] }).GetLocal(0)[instr](align, offset).Drop().End();
 | |
|                 break;
 | |
|             case "store":
 | |
|                 builder = builder.Function("set_" + offset, { params: ["i32"] }).GetLocal(0)[constInstr](0xdead)[instr](align, offset).End();
 | |
|                 break;
 | |
|             default:
 | |
|                 throw new Error(`Implementation problem: unknown memory access type ${info.type}`);
 | |
|             }
 | |
|         
 | |
|         builder = builder.End();
 | |
| 
 | |
|         const instance = new WebAssembly.Instance(new WebAssembly.Module(builder.WebAssembly().get()), { imp: { memory: memory } });
 | |
| 
 | |
|         for (let offset of offsets) {
 | |
|             for (let wiggle of wiggles) {
 | |
|                 const address = LLB.varuint32Max - offset - wiggle;
 | |
|                 if (verbose)
 | |
|                     print(`${op.name.padStart(16, ' ')}: base address ${address > 0 ? '0x' : '  '}${address.toString(16).padStart(8, address > 0 ? '0' : ' ')} + offset 0x${offset.toString(16).padStart(8, '0')} - wiggle ${wiggle} = effective address 0x${(address + offset - wiggle).toString(16).padStart(16, '0')}`);
 | |
|                 switch (info.type) {
 | |
|                 case "load":
 | |
|                     assert.throws(() => instance.exports["get_" + offset](address), WebAssembly.RuntimeError, `Out of bounds memory access`);
 | |
|                     break;
 | |
|                 case "store":
 | |
|                     assert.throws(() => instance.exports["set_" + offset](address), WebAssembly.RuntimeError, `Out of bounds memory access`);
 | |
|                     break;
 | |
|                 default: throw new Error(`Implementation problem: unknown memory access type ${info.type}`);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         fullGC();
 | |
|     }
 | |
| 
 | |
|     // Only check that the memory was untouched at the very end, before throwing it away entirely.
 | |
|     for (let idx = 0; idx < buf.byteLength; ++idx)
 | |
|         assert.eq(buf[idx], 0);
 | |
| }
 |