Changeset 246139 in webkit
- Timestamp:
- Jun 5, 2019 8:14:47 PM (5 years ago)
- Location:
- trunk
- Files:
-
- 3 added
- 1 deleted
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r246134 r246139 1 2019-06-05 Justin Michaud <justin_michaud@apple.com> 2 3 [WASM-References] Add support for Anyref tables, Table.get and Table.set (for Anyref only). 4 https://bugs.webkit.org/show_bug.cgi?id=198398 5 6 Reviewed by Saam Barati. 7 8 * wasm/references/anyref_table.js: Added. 9 (string_appeared_here.doGCSet): 10 (doGCTest): 11 (doGCSet.doGCTest.let.count.0.doBarrierSet): 12 * wasm/references/anyref_table_import.js: Added. 13 (makeImport): 14 (string_appeared_here.fullGC.assert.eq.1.exports.get_tbl.makeImport): 15 (string_appeared_here.fullGC.assert.eq.1.exports.get_tbl): 16 * wasm/references/is_null_error.js: Removed. 17 * wasm/references/validation.js: Added. 18 (assert.throws.new.WebAssembly.Module.bin): 19 (assert.throws): 20 * wasm/wasm.json: 21 1 22 2019-06-05 Justin Michaud <justin_michaud@apple.com> 2 23 -
trunk/JSTests/wasm/js-api/table.js
r235420 r246139 133 133 let badDescriptions = [ 134 134 [{initial: 10, element: "i32"}, 135 "WebAssembly.Module doesn't parse at byte 18: Table type should be anyfunc , got -1 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')",136 "WebAssembly.Module doesn't parse at byte 26: Table type should be anyfunc , got -1 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"],135 "WebAssembly.Module doesn't parse at byte 18: Table type should be anyfunc or anyref, got -1 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')", 136 "WebAssembly.Module doesn't parse at byte 26: Table type should be anyfunc or anyref, got -1 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"], 137 137 [{initial: 10, element: "f32"}, 138 "WebAssembly.Module doesn't parse at byte 18: Table type should be anyfunc , got -3 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')",139 "WebAssembly.Module doesn't parse at byte 26: Table type should be anyfunc , got -3 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"],138 "WebAssembly.Module doesn't parse at byte 18: Table type should be anyfunc or anyref, got -3 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')", 139 "WebAssembly.Module doesn't parse at byte 26: Table type should be anyfunc or anyref, got -3 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"], 140 140 [{initial: 10, element: "f64"}, 141 "WebAssembly.Module doesn't parse at byte 18: Table type should be anyfunc , got -4 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')",142 "WebAssembly.Module doesn't parse at byte 26: Table type should be anyfunc , got -4 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"],141 "WebAssembly.Module doesn't parse at byte 18: Table type should be anyfunc or anyref, got -4 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')", 142 "WebAssembly.Module doesn't parse at byte 26: Table type should be anyfunc or anyref, got -4 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"], 143 143 [{initial: 10, element: "i64"}, 144 "WebAssembly.Module doesn't parse at byte 18: Table type should be anyfunc , got -2 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')",145 "WebAssembly.Module doesn't parse at byte 26: Table type should be anyfunc , got -2 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"],144 "WebAssembly.Module doesn't parse at byte 18: Table type should be anyfunc or anyref, got -2 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')", 145 "WebAssembly.Module doesn't parse at byte 26: Table type should be anyfunc or anyref, got -2 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"], 146 146 [{initial: 10, maximum: 20, element: "i32"}, 147 "WebAssembly.Module doesn't parse at byte 18: Table type should be anyfunc , got -1 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')",148 "WebAssembly.Module doesn't parse at byte 26: Table type should be anyfunc , got -1 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"],147 "WebAssembly.Module doesn't parse at byte 18: Table type should be anyfunc or anyref, got -1 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')", 148 "WebAssembly.Module doesn't parse at byte 26: Table type should be anyfunc or anyref, got -1 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"], 149 149 [{initial: 10, maximum: 20, element: "f32"}, 150 "WebAssembly.Module doesn't parse at byte 18: Table type should be anyfunc , got -3 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')",151 "WebAssembly.Module doesn't parse at byte 26: Table type should be anyfunc , got -3 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"],150 "WebAssembly.Module doesn't parse at byte 18: Table type should be anyfunc or anyref, got -3 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')", 151 "WebAssembly.Module doesn't parse at byte 26: Table type should be anyfunc or anyref, got -3 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"], 152 152 [{initial: 10, maximum: 20, element: "f64"}, 153 "WebAssembly.Module doesn't parse at byte 18: Table type should be anyfunc , got -4 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')",154 "WebAssembly.Module doesn't parse at byte 26: Table type should be anyfunc , got -4 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"],153 "WebAssembly.Module doesn't parse at byte 18: Table type should be anyfunc or anyref, got -4 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')", 154 "WebAssembly.Module doesn't parse at byte 26: Table type should be anyfunc or anyref, got -4 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"], 155 155 [{initial: 10, maximum: 20, element: "i64"}, 156 "WebAssembly.Module doesn't parse at byte 18: Table type should be anyfunc , got -2 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')",157 "WebAssembly.Module doesn't parse at byte 26: Table type should be anyfunc , got -2 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"],156 "WebAssembly.Module doesn't parse at byte 18: Table type should be anyfunc or anyref, got -2 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')", 157 "WebAssembly.Module doesn't parse at byte 26: Table type should be anyfunc or anyref, got -2 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"], 158 158 159 159 [{initial: 10, maximum: 9, element: "anyfunc"}, -
trunk/JSTests/wasm/wasm.json
r245496 r246139 19 19 "value_type": ["i32", "i64", "f32", "f64", "anyref"], 20 20 "block_type": ["i32", "i64", "f32", "f64", "void", "anyref"], 21 "elem_type": ["anyfunc" ],21 "elem_type": ["anyfunc","anyref"], 22 22 "external_kind": { 23 23 "Function": { "type": "uint8", "value": 0 }, … … 67 67 "get_global": { "category": "special", "value": 35, "return": ["any"], "parameter": [], "immediate": [{"name": "global_index", "type": "varuint32"}], "description": "read a global variable" }, 68 68 "set_global": { "category": "special", "value": 36, "return": [], "parameter": ["any"], "immediate": [{"name": "global_index", "type": "varuint32"}], "description": "write a global variable" }, 69 "table.get": { "category": "special", "value": 37, "return": ["anyref"], "parameter": ["i32"], "immediate": [], "description": "get a table value" }, 70 "table.set": { "category": "special", "value": 38, "return": [], "parameter": ["i32", "anyref"], "immediate": [], "description": "set a table value" }, 69 71 "call": { "category": "call", "value": 16, "return": ["call"], "parameter": ["call"], "immediate": [{"name": "function_index", "type": "varuint32"}], "description": "call a function by its index" }, 70 72 "call_indirect": { "category": "call", "value": 17, "return": ["call"], "parameter": ["call"], "immediate": [{"name": "type_index", "type": "varuint32"}, {"name": "reserved", "type": "varuint1"}], "description": "call a function indirect with an expected signature" }, -
trunk/Source/JavaScriptCore/ChangeLog
r246134 r246139 1 2019-06-05 Justin Michaud <justin_michaud@apple.com> 2 3 [WASM-References] Add support for Anyref tables, Table.get and Table.set (for Anyref only). 4 https://bugs.webkit.org/show_bug.cgi?id=198398 5 6 Reviewed by Saam Barati. 7 8 Create a new table subtype called FuncRefTable (note: Anyfunc was renamed to Funcref in the references spec). 9 Table now write-barriers and visits its children's wrapper objects. FuncRefTable caches some extra data to 10 support calling from wasm. A JSWebAssemblyTable is required to set an anyref element, but this is only because 11 we need to write barrier it (so it should not restrict how we implement threads). This patch does, however, 12 restrict the implementation of function references to require every Ref.func to have an associated wrapper. This 13 can be done statically, so this too should not restrict our threads implementation. 14 15 * wasm/WasmAirIRGenerator.cpp: 16 (JSC::Wasm::AirIRGenerator::addTableGet): 17 (JSC::Wasm::AirIRGenerator::addTableSet): 18 (JSC::Wasm::AirIRGenerator::addCallIndirect): 19 * wasm/WasmB3IRGenerator.cpp: 20 (JSC::Wasm::B3IRGenerator::addLocal): 21 (JSC::Wasm::B3IRGenerator::addTableGet): 22 (JSC::Wasm::B3IRGenerator::addTableSet): 23 (JSC::Wasm::B3IRGenerator::addCallIndirect): 24 * wasm/WasmFormat.h: 25 (JSC::Wasm::TableInformation::TableInformation): 26 (JSC::Wasm::TableInformation::type const): 27 * wasm/WasmFunctionParser.h: 28 (JSC::Wasm::FunctionParser<Context>::parseExpression): 29 (JSC::Wasm::FunctionParser<Context>::parseUnreachableExpression): 30 * wasm/WasmSectionParser.cpp: 31 (JSC::Wasm::SectionParser::parseTableHelper): 32 * wasm/WasmTable.cpp: 33 (JSC::Wasm::Table::Table): 34 (JSC::Wasm::Table::tryCreate): 35 (JSC::Wasm::Table::grow): 36 (JSC::Wasm::Table::clear): 37 (JSC::Wasm::Table::set): 38 (JSC::Wasm::Table::get): 39 (JSC::Wasm::Table::visitChildren): 40 (JSC::Wasm::FuncRefTable::FuncRefTable): 41 (JSC::Wasm::FuncRefTable::setFunction): 42 (JSC::Wasm::Table::~Table): Deleted. 43 (JSC::Wasm::Table::clearFunction): Deleted. 44 (JSC::Wasm::Table::setFunction): Deleted. 45 * wasm/WasmTable.h: 46 (JSC::Wasm::Table::length const): 47 (JSC::Wasm::Table::type const): 48 (JSC::Wasm::Table::setOwner): 49 (JSC::Wasm::FuncRefTable::offsetOfFunctions): 50 (JSC::Wasm::FuncRefTable::offsetOfInstances): 51 (JSC::Wasm::Table::offsetOfFunctions): Deleted. 52 (JSC::Wasm::Table::offsetOfInstances): Deleted. 53 * wasm/WasmValidate.cpp: 54 (JSC::Wasm::Validate::addTableGet): 55 (JSC::Wasm::Validate::addTableSet): 56 (JSC::Wasm::Validate::addCallIndirect): 57 * wasm/js/JSWebAssemblyTable.cpp: 58 (JSC::JSWebAssemblyTable::JSWebAssemblyTable): 59 (JSC::JSWebAssemblyTable::finishCreation): 60 (JSC::JSWebAssemblyTable::visitChildren): 61 (JSC::JSWebAssemblyTable::grow): 62 (JSC::JSWebAssemblyTable::get): 63 (JSC::JSWebAssemblyTable::set): 64 (JSC::JSWebAssemblyTable::clear): 65 (JSC::JSWebAssemblyTable::getFunction): Deleted. 66 (JSC::JSWebAssemblyTable::clearFunction): Deleted. 67 (JSC::JSWebAssemblyTable::setFunction): Deleted. 68 * wasm/js/JSWebAssemblyTable.h: 69 * wasm/js/WebAssemblyModuleRecord.cpp: 70 (JSC::WebAssemblyModuleRecord::link): 71 (JSC::WebAssemblyModuleRecord::evaluate): 72 * wasm/js/WebAssemblyTableConstructor.cpp: 73 (JSC::constructJSWebAssemblyTable): 74 * wasm/js/WebAssemblyTablePrototype.cpp: 75 (JSC::webAssemblyTableProtoFuncGet): 76 (JSC::webAssemblyTableProtoFuncSet): 77 * wasm/wasm.json: 78 1 79 2019-06-05 Justin Michaud <justin_michaud@apple.com> 2 80 -
trunk/Source/JavaScriptCore/wasm/WasmAirIRGenerator.cpp
r245895 r246139 233 233 ExpressionType addConstant(BasicBlock*, Type, uint64_t); 234 234 235 // References 235 236 PartialResult WARN_UNUSED_RETURN addRefIsNull(ExpressionType& value, ExpressionType& result); 237 238 // Tables 239 PartialResult WARN_UNUSED_RETURN addTableGet(ExpressionType& idx, ExpressionType& result); 240 PartialResult WARN_UNUSED_RETURN addTableSet(ExpressionType& idx, ExpressionType& value); 236 241 237 242 // Locals … … 950 955 } 951 956 957 auto AirIRGenerator::addTableGet(ExpressionType& idx, ExpressionType& result) -> PartialResult 958 { 959 // FIXME: Emit this inline <https://bugs.webkit.org/show_bug.cgi?id=198506>. 960 ASSERT(idx.tmp()); 961 ASSERT(idx.type() == Type::I32); 962 result = tmpForType(Type::Anyref); 963 964 uint64_t (*doGet)(Instance*, int32_t) = [] (Instance* instance, int32_t idx) -> uint64_t { 965 return JSValue::encode(instance->table()->get(idx)); 966 }; 967 968 emitCCall(doGet, result, instanceValue(), idx); 969 970 return { }; 971 } 972 973 auto AirIRGenerator::addTableSet(ExpressionType& idx, ExpressionType& value) -> PartialResult 974 { 975 // FIXME: Emit this inline <https://bugs.webkit.org/show_bug.cgi?id=198506>. 976 ASSERT(idx.tmp()); 977 ASSERT(idx.type() == Type::I32); 978 ASSERT(value.tmp()); 979 980 void (*doSet)(Instance*, int32_t, uint64_t value) = [] (Instance* instance, int32_t idx, uint64_t value) -> void { 981 // FIXME: We need to box wasm Funcrefs once they are supported here. 982 // <https://bugs.webkit.org/show_bug.cgi?id=198157> 983 instance->table()->set(idx, JSValue::decode(value)); 984 }; 985 986 emitCCall(doSet, TypedTmp(), instanceValue(), idx, value); 987 988 return { }; 989 } 990 952 991 auto AirIRGenerator::getLocal(uint32_t index, ExpressionType& result) -> PartialResult 953 992 { … … 1842 1881 ExpressionType calleeIndex = args.takeLast(); 1843 1882 ASSERT(signature.argumentCount() == args.size()); 1883 ASSERT(m_info.tableInformation.type() == TableElementType::Funcref); 1844 1884 1845 1885 m_makesCalls = true; … … 1857 1897 { 1858 1898 RELEASE_ASSERT(Arg::isValidAddrForm(Instance::offsetOfTable(), B3::Width64)); 1859 RELEASE_ASSERT(Arg::isValidAddrForm( Table::offsetOfFunctions(), B3::Width64));1860 RELEASE_ASSERT(Arg::isValidAddrForm( Table::offsetOfInstances(), B3::Width64));1861 RELEASE_ASSERT(Arg::isValidAddrForm( Table::offsetOfLength(), B3::Width64));1899 RELEASE_ASSERT(Arg::isValidAddrForm(FuncRefTable::offsetOfFunctions(), B3::Width64)); 1900 RELEASE_ASSERT(Arg::isValidAddrForm(FuncRefTable::offsetOfInstances(), B3::Width64)); 1901 RELEASE_ASSERT(Arg::isValidAddrForm(FuncRefTable::offsetOfLength(), B3::Width64)); 1862 1902 1863 1903 append(Move, Arg::addr(instanceValue(), Instance::offsetOfTable()), callableFunctionBufferLength); 1864 append(Move, Arg::addr(callableFunctionBufferLength, Table::offsetOfFunctions()), callableFunctionBuffer);1865 append(Move, Arg::addr(callableFunctionBufferLength, Table::offsetOfInstances()), instancesBuffer);1904 append(Move, Arg::addr(callableFunctionBufferLength, FuncRefTable::offsetOfFunctions()), callableFunctionBuffer); 1905 append(Move, Arg::addr(callableFunctionBufferLength, FuncRefTable::offsetOfInstances()), instancesBuffer); 1866 1906 append(Move32, Arg::addr(callableFunctionBufferLength, Table::offsetOfLength()), callableFunctionBufferLength); 1867 1907 } -
trunk/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp
r245895 r246139 186 186 ExpressionType addConstant(Type, uint64_t); 187 187 188 // References 188 189 PartialResult WARN_UNUSED_RETURN addRefIsNull(ExpressionType& value, ExpressionType& result); 190 191 // Tables 192 PartialResult WARN_UNUSED_RETURN addTableGet(ExpressionType& idx, ExpressionType& result); 193 PartialResult WARN_UNUSED_RETURN addTableSet(ExpressionType& idx, ExpressionType& value); 189 194 190 195 // Locals … … 562 567 } 563 568 569 auto B3IRGenerator::addTableGet(ExpressionType& idx, ExpressionType& result) -> PartialResult 570 { 571 // FIXME: Emit this inline <https://bugs.webkit.org/show_bug.cgi?id=198506>. 572 uint64_t (*doGet)(Instance*, int32_t) = [] (Instance* instance, int32_t idx) -> uint64_t { 573 return JSValue::encode(instance->table()->get(idx)); 574 }; 575 576 result = m_currentBlock->appendNew<CCallValue>(m_proc, toB3Type(Anyref), origin(), 577 m_currentBlock->appendNew<ConstPtrValue>(m_proc, origin(), tagCFunctionPtr<void*>(doGet, B3CCallPtrTag)), 578 instanceValue(), idx); 579 580 return { }; 581 } 582 583 auto B3IRGenerator::addTableSet(ExpressionType& idx, ExpressionType& value) -> PartialResult 584 { 585 // FIXME: Emit this inline <https://bugs.webkit.org/show_bug.cgi?id=198506>. 586 void (*doSet)(Instance*, int32_t, uint64_t value) = [] (Instance* instance, int32_t idx, uint64_t value) -> void { 587 // FIXME: We need to box wasm Funcrefs once they are supported here. 588 // <https://bugs.webkit.org/show_bug.cgi?id=198157> 589 instance->table()->set(idx, JSValue::decode(value)); 590 }; 591 592 m_currentBlock->appendNew<CCallValue>(m_proc, B3::Void, origin(), 593 m_currentBlock->appendNew<ConstPtrValue>(m_proc, origin(), tagCFunctionPtr<void*>(doSet, B3CCallPtrTag)), 594 instanceValue(), idx, value); 595 596 return { }; 597 } 598 564 599 auto B3IRGenerator::getLocal(uint32_t index, ExpressionType& result) -> PartialResult 565 600 { … … 1264 1299 instanceValue(), safeCast<int32_t>(Instance::offsetOfTable())); 1265 1300 callableFunctionBuffer = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, pointerType(), origin(), 1266 table, safeCast<int32_t>( Table::offsetOfFunctions()));1301 table, safeCast<int32_t>(FuncRefTable::offsetOfFunctions())); 1267 1302 instancesBuffer = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, pointerType(), origin(), 1268 table, safeCast<int32_t>( Table::offsetOfInstances()));1303 table, safeCast<int32_t>(FuncRefTable::offsetOfInstances())); 1269 1304 callableFunctionBufferLength = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, Int32, origin(), 1270 1305 table, safeCast<int32_t>(Table::offsetOfLength())); -
trunk/Source/JavaScriptCore/wasm/WasmFormat.h
r245496 r246139 55 55 struct ModuleInformation; 56 56 57 enum class TableElementType : uint8_t { 58 Anyref, 59 Funcref 60 }; 61 57 62 inline bool isValueType(Type type) 58 63 { … … 215 220 } 216 221 217 TableInformation(uint32_t initial, Optional<uint32_t> maximum, bool isImport )222 TableInformation(uint32_t initial, Optional<uint32_t> maximum, bool isImport, TableElementType type) 218 223 : m_initial(initial) 219 224 , m_maximum(maximum) 220 225 , m_isImport(isImport) 221 226 , m_isValid(true) 227 , m_type(type) 222 228 { 223 229 ASSERT(*this); … … 228 234 uint32_t initial() const { return m_initial; } 229 235 Optional<uint32_t> maximum() const { return m_maximum; } 236 TableElementType type() const { return m_type; } 230 237 231 238 private: … … 234 241 bool m_isImport { false }; 235 242 bool m_isValid { false }; 243 TableElementType m_type; 236 244 }; 237 245 -
trunk/Source/JavaScriptCore/wasm/WasmFunctionParser.h
r245496 r246139 282 282 } 283 283 284 case TableGet: { 285 WASM_PARSER_FAIL_IF(!Options::useWebAssemblyReferences(), "references are not enabled"); 286 ExpressionType result, idx; 287 WASM_TRY_POP_EXPRESSION_STACK_INTO(idx, "table.get"); 288 WASM_TRY_ADD_TO_CONTEXT(addTableGet(idx, result)); 289 m_expressionStack.append(result); 290 return { }; 291 } 292 293 case TableSet: { 294 WASM_PARSER_FAIL_IF(!Options::useWebAssemblyReferences(), "references are not enabled"); 295 ExpressionType val, idx; 296 WASM_TRY_POP_EXPRESSION_STACK_INTO(val, "table.set"); 297 WASM_TRY_POP_EXPRESSION_STACK_INTO(idx, "table.set"); 298 WASM_TRY_ADD_TO_CONTEXT(addTableSet(idx, val)); 299 return { }; 300 } 301 284 302 case RefNull: { 285 303 WASM_PARSER_FAIL_IF(!Options::useWebAssemblyReferences(), "references are not enabled"); … … 374 392 WASM_PARSER_FAIL_IF(reserved, "call_indirect's 'reserved' varuint1 must be 0x0"); 375 393 WASM_PARSER_FAIL_IF(m_info.usedSignatures.size() <= signatureIndex, "call_indirect's signature index ", signatureIndex, " exceeds known signatures ", m_info.usedSignatures.size()); 394 WASM_PARSER_FAIL_IF(m_info.tableInformation.type() != TableElementType::Funcref, "call_indirect is only valid when a table has type anyfunc"); 376 395 377 396 const Signature& calleeSignature = m_info.usedSignatures[signatureIndex].get(); … … 655 674 } 656 675 676 case TableGet: 677 case TableSet: 678 case RefIsNull: 657 679 case RefNull: { 658 WASM_PARSER_FAIL_IF(!Options::useWebAssemblyReferences(), "references are not enabled");659 return { };660 }661 662 case RefIsNull: {663 680 WASM_PARSER_FAIL_IF(!Options::useWebAssemblyReferences(), "references are not enabled"); 664 681 return { }; -
trunk/Source/JavaScriptCore/wasm/WasmSectionParser.cpp
r245765 r246139 197 197 int8_t type; 198 198 WASM_PARSER_FAIL_IF(!parseInt7(type), "can't parse Table type"); 199 WASM_PARSER_FAIL_IF(type != Wasm::Anyfunc , "Table type should be anyfunc, got ", type);199 WASM_PARSER_FAIL_IF(type != Wasm::Anyfunc && type != Wasm::Anyref, "Table type should be anyfunc or anyref, got ", type); 200 200 201 201 uint32_t initial; … … 208 208 ASSERT(!maximum || *maximum >= initial); 209 209 210 m_info->tableInformation = TableInformation(initial, maximum, isImport); 210 TableElementType tableType = type == Wasm::Anyfunc ? TableElementType::Funcref : TableElementType::Anyref; 211 m_info->tableInformation = TableInformation(initial, maximum, isImport, tableType); 211 212 212 213 return { }; -
trunk/Source/JavaScriptCore/wasm/WasmTable.cpp
r239427 r246139 48 48 } 49 49 50 RefPtr<Table> Table::tryCreate(uint32_t initial, Optional<uint32_t> maximum) 51 { 52 if (!isValidLength(initial)) 53 return nullptr; 54 return adoptRef(new (NotNull, fastMalloc(sizeof(Table))) Table(initial, maximum)); 55 } 56 57 Table::~Table() 58 { 59 } 60 61 Table::Table(uint32_t initial, Optional<uint32_t> maximum) 50 Table::Table(uint32_t initial, Optional<uint32_t> maximum, TableElementType type) 51 : m_type(type) 52 , m_maximum(maximum) 53 , m_owner(nullptr) 62 54 { 63 55 setLength(initial); 64 m_maximum = maximum;65 56 ASSERT(!m_maximum || *m_maximum >= m_length); 66 57 67 58 // FIXME: It might be worth trying to pre-allocate maximum here. The spec recommends doing so. 68 59 // But for now, we're not doing that. 69 m_importableFunctions = MallocPtr<WasmToWasmImportableFunction>::malloc((sizeof(WasmToWasmImportableFunction) * Checked<size_t>(allocatedLength(m_length))).unsafeGet());70 60 // FIXME this over-allocates and could be smarter about not committing all of that memory https://bugs.webkit.org/show_bug.cgi?id=181425 71 m_ instances = MallocPtr<Instance*>::malloc((sizeof(Instance*) * Checked<size_t>(allocatedLength(m_length))).unsafeGet());61 m_jsValues = MallocPtr<WriteBarrier<Unknown>>::malloc((sizeof(WriteBarrier<Unknown>) * Checked<size_t>(allocatedLength(m_length))).unsafeGet()); 72 62 for (uint32_t i = 0; i < allocatedLength(m_length); ++i) { 73 new (&m_importableFunctions.get()[i]) WasmToWasmImportableFunction(); 74 ASSERT(m_importableFunctions.get()[i].signatureIndex == Wasm::Signature::invalidIndex); // We rely on this in compiled code. 75 m_instances.get()[i] = nullptr; 63 new (&m_jsValues.get()[i]) WriteBarrier<Unknown>(); 64 m_jsValues.get()[i].setStartingValue(jsNull()); 65 } 66 } 67 68 RefPtr<Table> Table::tryCreate(uint32_t initial, Optional<uint32_t> maximum, TableElementType type) 69 { 70 if (!isValidLength(initial)) 71 return nullptr; 72 switch (type) { 73 case TableElementType::Funcref: 74 return adoptRef(new FuncRefTable(initial, maximum)); 75 case TableElementType::Anyref: 76 return adoptRef(new Table(initial, maximum)); 76 77 } 77 78 } … … 79 80 Optional<uint32_t> Table::grow(uint32_t delta) 80 81 { 82 RELEASE_ASSERT(m_owner); 81 83 if (delta == 0) 82 84 return length(); 85 86 auto locker = holdLock(m_owner->cellLock()); 83 87 84 88 using Checked = Checked<uint32_t, RecordOverflow>; … … 109 113 }; 110 114 111 if (!checkedGrow(m_importableFunctions)) 112 return WTF::nullopt; 113 if (!checkedGrow(m_instances)) 115 if (auto* funcRefTable = asFuncrefTable()) { 116 if (!checkedGrow(funcRefTable->m_importableFunctions)) 117 return WTF::nullopt; 118 if (!checkedGrow(funcRefTable->m_instances)) 119 return WTF::nullopt; 120 } 121 122 if (!checkedGrow(m_jsValues)) 114 123 return WTF::nullopt; 115 124 116 125 setLength(newLength); 117 118 126 return newLength; 119 127 } 120 128 121 void Table::clear Function(uint32_t index)129 void Table::clear(uint32_t index) 122 130 { 123 131 RELEASE_ASSERT(index < length()); 124 m_importableFunctions.get()[index & m_mask] = WasmToWasmImportableFunction(); 125 ASSERT(m_importableFunctions.get()[index & m_mask].signatureIndex == Wasm::Signature::invalidIndex); // We rely on this in compiled code. 126 m_instances.get()[index & m_mask] = nullptr; 132 RELEASE_ASSERT(m_owner); 133 if (auto* funcRefTable = asFuncrefTable()) { 134 funcRefTable->m_importableFunctions.get()[index & m_mask] = WasmToWasmImportableFunction(); 135 ASSERT(funcRefTable->m_importableFunctions.get()[index & m_mask].signatureIndex == Wasm::Signature::invalidIndex); // We rely on this in compiled code. 136 funcRefTable->m_instances.get()[index & m_mask] = nullptr; 137 } 138 m_jsValues.get()[index & m_mask].setStartingValue(jsNull()); 127 139 } 128 140 129 void Table::set Function(uint32_t index, WasmToWasmImportableFunction function, Instance* instance)141 void Table::set(uint32_t index, JSValue value) 130 142 { 131 143 RELEASE_ASSERT(index < length()); 144 RELEASE_ASSERT(isAnyrefTable()); 145 RELEASE_ASSERT(m_owner); 146 clear(index); 147 m_jsValues.get()[index & m_mask].set(*m_owner->vm(), m_owner, value); 148 } 149 150 JSValue Table::get(uint32_t index) const 151 { 152 RELEASE_ASSERT(index < length()); 153 RELEASE_ASSERT(m_owner); 154 return m_jsValues.get()[index & m_mask].get(); 155 } 156 157 void Table::visitChildren(SlotVisitor& visitor) 158 { 159 RELEASE_ASSERT(m_owner); 160 auto locker = holdLock(m_owner->cellLock()); 161 for (unsigned i = 0; i < m_length; ++i) 162 visitor.append(m_jsValues.get()[i]); 163 } 164 165 FuncRefTable* Table::asFuncrefTable() 166 { 167 return m_type == TableElementType::Funcref ? static_cast<FuncRefTable*>(this) : nullptr; 168 } 169 170 FuncRefTable::FuncRefTable(uint32_t initial, Optional<uint32_t> maximum) 171 : Table(initial, maximum, TableElementType::Funcref) 172 { 173 // FIXME: It might be worth trying to pre-allocate maximum here. The spec recommends doing so. 174 // But for now, we're not doing that. 175 m_importableFunctions = MallocPtr<WasmToWasmImportableFunction>::malloc((sizeof(WasmToWasmImportableFunction) * Checked<size_t>(allocatedLength(m_length))).unsafeGet()); 176 // FIXME this over-allocates and could be smarter about not committing all of that memory https://bugs.webkit.org/show_bug.cgi?id=181425 177 m_instances = MallocPtr<Instance*>::malloc((sizeof(Instance*) * Checked<size_t>(allocatedLength(m_length))).unsafeGet()); 178 for (uint32_t i = 0; i < allocatedLength(m_length); ++i) { 179 new (&m_importableFunctions.get()[i]) WasmToWasmImportableFunction(); 180 ASSERT(m_importableFunctions.get()[i].signatureIndex == Wasm::Signature::invalidIndex); // We rely on this in compiled code. 181 m_instances.get()[i] = nullptr; 182 } 183 } 184 185 void FuncRefTable::setFunction(uint32_t index, JSObject* optionalWrapper, WasmToWasmImportableFunction function, Instance* instance) 186 { 187 RELEASE_ASSERT(index < length()); 188 RELEASE_ASSERT(m_owner); 189 clear(index); 190 if (optionalWrapper) 191 m_jsValues.get()[index & m_mask].set(*m_owner->vm(), m_owner, optionalWrapper); 132 192 m_importableFunctions.get()[index & m_mask] = function; 133 193 m_instances.get()[index & m_mask] = instance; -
trunk/Source/JavaScriptCore/wasm/WasmTable.h
r239427 r246139 30 30 #include "WasmFormat.h" 31 31 #include "WasmLimits.h" 32 #include "WriteBarrier.h" 32 33 #include <wtf/MallocPtr.h> 33 34 #include <wtf/Optional.h> … … 38 39 39 40 class Instance; 41 class FuncRefTable; 40 42 41 43 class Table : public ThreadSafeRefCounted<Table> { 44 WTF_MAKE_NONCOPYABLE(Table); 45 WTF_MAKE_FAST_ALLOCATED(Table); 42 46 public: 43 static RefPtr<Table> tryCreate(uint32_t initial, Optional<uint32_t> maximum );47 static RefPtr<Table> tryCreate(uint32_t initial, Optional<uint32_t> maximum, TableElementType); 44 48 45 JS_EXPORT_PRIVATE ~Table() ;49 JS_EXPORT_PRIVATE ~Table() = default; 46 50 47 51 Optional<uint32_t> maximum() const { return m_maximum; } 48 52 uint32_t length() const { return m_length; } 49 Optional<uint32_t> grow(uint32_t delta) WARN_UNUSED_RETURN;50 void clearFunction(uint32_t);51 void setFunction(uint32_t, WasmToWasmImportableFunction, Instance*);52 53 53 static ptrdiff_t offsetOfFunctions() { return OBJECT_OFFSETOF(Table, m_importableFunctions); }54 static ptrdiff_t offsetOfInstances() { return OBJECT_OFFSETOF(Table, m_instances); }55 54 static ptrdiff_t offsetOfLength() { return OBJECT_OFFSETOF(Table, m_length); } 56 55 static ptrdiff_t offsetOfMask() { return OBJECT_OFFSETOF(Table, m_mask); } … … 58 57 static uint32_t allocatedLength(uint32_t length); 59 58 uint32_t mask() const { return m_mask; } 59 60 void setOwner(JSObject* owner) 61 { 62 ASSERT(!m_owner); 63 ASSERT(owner); 64 m_owner = owner; 65 } 66 67 TableElementType type() const { return m_type; } 68 bool isAnyrefTable() const { return m_type == TableElementType::Anyref; } 69 FuncRefTable* asFuncrefTable(); 70 60 71 static bool isValidLength(uint32_t length) { return length < maxTableEntries; } 61 72 62 private: 63 Table(uint32_t initial, Optional<uint32_t> maximum); 73 void clear(uint32_t); 74 void set(uint32_t, JSValue); 75 JSValue get(uint32_t) const; 76 77 Optional<uint32_t> grow(uint32_t delta); 78 79 void visitChildren(SlotVisitor&); 80 81 protected: 82 Table(uint32_t initial, Optional<uint32_t> maximum, TableElementType = TableElementType::Anyref); 64 83 65 84 void setLength(uint32_t); 85 86 uint32_t m_length; 87 uint32_t m_mask; 88 const TableElementType m_type; 89 const Optional<uint32_t> m_maximum; 90 91 MallocPtr<WriteBarrier<Unknown>> m_jsValues; 92 JSObject* m_owner; 93 }; 94 95 class FuncRefTable : public Table { 96 public: 97 JS_EXPORT_PRIVATE ~FuncRefTable() = default; 98 99 void setFunction(uint32_t, JSObject*, WasmToWasmImportableFunction, Instance*); 100 101 static ptrdiff_t offsetOfFunctions() { return OBJECT_OFFSETOF(FuncRefTable, m_importableFunctions); } 102 static ptrdiff_t offsetOfInstances() { return OBJECT_OFFSETOF(FuncRefTable, m_instances); } 103 104 private: 105 FuncRefTable(uint32_t initial, Optional<uint32_t> maximum); 66 106 67 107 MallocPtr<WasmToWasmImportableFunction> m_importableFunctions; 68 108 // call_indirect needs to do an Instance check to potentially context switch when calling a function to another instance. We can hold raw pointers to Instance here because the embedder ensures that Table keeps all the instances alive. We couldn't hold a Ref here because it would cause cycles. 69 109 MallocPtr<Instance*> m_instances; 70 uint32_t m_length; 71 uint32_t m_mask; 72 Optional<uint32_t> m_maximum; 110 111 friend class Table; 73 112 }; 74 113 -
trunk/Source/JavaScriptCore/wasm/WasmValidate.cpp
r245496 r246139 101 101 ExpressionType addConstant(Type type, uint64_t) { return type; } 102 102 103 // References 103 104 Result WARN_UNUSED_RETURN addRefIsNull(ExpressionType& value, ExpressionType& result); 105 106 // Tables 107 Result WARN_UNUSED_RETURN addTableGet(ExpressionType& idx, ExpressionType& result); 108 Result WARN_UNUSED_RETURN addTableSet(ExpressionType& idx, ExpressionType& value); 104 109 105 110 // Locals … … 172 177 } 173 178 179 auto Validate::addTableGet(ExpressionType& idx, ExpressionType& result) -> Result 180 { 181 result = Type::Anyref; 182 WASM_VALIDATOR_FAIL_IF(Type::I32 != idx, "table.get index to type ", idx, " expected ", Type::I32); 183 WASM_VALIDATOR_FAIL_IF(TableElementType::Anyref != m_module.tableInformation.type(), "table.get expects the table to have type ", Type::Anyref); 184 185 return { }; 186 } 187 188 auto Validate::addTableSet(ExpressionType& idx, ExpressionType& value) -> Result 189 { 190 WASM_VALIDATOR_FAIL_IF(Type::I32 != idx, "table.set index to type ", idx, " expected ", Type::I32); 191 WASM_VALIDATOR_FAIL_IF(Type::Anyref != value, "table.set value to type ", value, " expected ", Type::Anyref); 192 WASM_VALIDATOR_FAIL_IF(TableElementType::Anyref != m_module.tableInformation.type(), "table.set expects the table to have type ", Type::Anyref); 193 194 return { }; 195 } 196 174 197 auto Validate::addRefIsNull(ExpressionType& value, ExpressionType& result) -> Result 175 198 { … … 347 370 auto Validate::addCallIndirect(const Signature& signature, const Vector<ExpressionType>& args, ExpressionType& result) -> Result 348 371 { 372 WASM_VALIDATOR_FAIL_IF(m_module.tableInformation.type() != TableElementType::Funcref, "Table must have type Anyfunc to call"); 349 373 const auto argumentCount = signature.argumentCount(); 350 374 WASM_VALIDATOR_FAIL_IF(argumentCount != args.size() - 1, "arity mismatch in call_indirect, got ", args.size() - 1, " arguments, expected ", argumentCount); -
trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyTable.cpp
r242123 r246139 48 48 49 49 auto* instance = new (NotNull, allocateCell<JSWebAssemblyTable>(vm.heap)) JSWebAssemblyTable(vm, structure, WTFMove(table)); 50 instance->table()->setOwner(instance); 50 51 instance->finishCreation(vm); 51 52 return instance; … … 61 62 , m_table(WTFMove(table)) 62 63 { 63 // FIXME: It might be worth trying to pre-allocate maximum here. The spec recommends doing so.64 // But for now, we're not doing that.65 // FIXME this over-allocates and could be smarter about not committing all of that memory https://bugs.webkit.org/show_bug.cgi?id=18142566 m_jsFunctions = MallocPtr<WriteBarrier<JSObject>>::malloc((sizeof(WriteBarrier<JSObject>) * Checked<size_t>(allocatedLength())).unsafeGet());67 for (uint32_t i = 0; i < allocatedLength(); ++i)68 new(&m_jsFunctions.get()[i]) WriteBarrier<JSObject>();69 64 } 70 65 … … 86 81 87 82 Base::visitChildren(thisObject, visitor); 88 89 for (unsigned i = 0; i < thisObject->length(); ++i) 90 visitor.append(thisObject->m_jsFunctions.get()[i]); 83 thisObject->table()->visitChildren(visitor); 91 84 } 92 85 … … 95 88 if (delta == 0) 96 89 return true; 97 98 size_t oldLength = length(); 99 100 auto grew = m_table->grow(delta); 101 if (!grew) 102 return false; 103 104 size_t newLength = grew.value(); 105 if (newLength > m_table->allocatedLength(oldLength)) 106 // FIXME this over-allocates and could be smarter about not committing all of that memory https://bugs.webkit.org/show_bug.cgi?id=181425 107 m_jsFunctions.realloc((sizeof(WriteBarrier<JSObject>) * Checked<size_t>(m_table->allocatedLength(newLength))).unsafeGet()); 108 109 for (size_t i = oldLength; i < m_table->allocatedLength(newLength); ++i) 110 new (&m_jsFunctions.get()[i]) WriteBarrier<JSObject>(); 111 112 return true; 90 return !!m_table->grow(delta); 113 91 } 114 92 115 JS Object* JSWebAssemblyTable::getFunction(uint32_t index)93 JSValue JSWebAssemblyTable::get(uint32_t index) 116 94 { 117 95 RELEASE_ASSERT(index < length()); 118 return m_ jsFunctions.get()[index & m_table->mask()].get();96 return m_table->get(index); 119 97 } 120 98 121 void JSWebAssemblyTable:: clearFunction(uint32_t index)99 void JSWebAssemblyTable::set(uint32_t index, JSValue value) 122 100 { 123 m_table->clearFunction(index); 124 m_jsFunctions.get()[index & m_table->mask()] = WriteBarrier<JSObject>(); 101 RELEASE_ASSERT(index < length()); 102 RELEASE_ASSERT(m_table->isAnyrefTable()); 103 m_table->set(index, value); 125 104 } 126 105 127 void JSWebAssemblyTable::set Function(VM& vm,uint32_t index, WebAssemblyFunction* function)106 void JSWebAssemblyTable::set(uint32_t index, WebAssemblyFunction* function) 128 107 { 129 m_table->setFunction(index, function->importableFunction(), &function->instance()->instance()); 130 m_jsFunctions.get()[index & m_table->mask()].set(vm, this, function); 108 RELEASE_ASSERT(index < length()); 109 RELEASE_ASSERT(m_table->asFuncrefTable()); 110 auto& subThis = *static_cast<Wasm::FuncRefTable*>(&m_table.get()); 111 subThis.setFunction(index, function, function->importableFunction(), &function->instance()->instance()); 131 112 } 132 113 133 void JSWebAssemblyTable::set Function(VM& vm,uint32_t index, WebAssemblyWrapperFunction* function)114 void JSWebAssemblyTable::set(uint32_t index, WebAssemblyWrapperFunction* function) 134 115 { 135 m_table->setFunction(index, function->importableFunction(), &function->instance()->instance()); 136 m_jsFunctions.get()[index & m_table->mask()].set(vm, this, function); 116 RELEASE_ASSERT(index < length()); 117 RELEASE_ASSERT(m_table->asFuncrefTable()); 118 auto& subThis = *static_cast<Wasm::FuncRefTable*>(&m_table.get()); 119 subThis.setFunction(index, function, function->importableFunction(), &function->instance()->instance()); 120 } 121 122 void JSWebAssemblyTable::clear(uint32_t index) 123 { 124 RELEASE_ASSERT(index < length()); 125 m_table->clear(index); 137 126 } 138 127 -
trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyTable.h
r242123 r246139 53 53 uint32_t allocatedLength() const { return m_table->allocatedLength(length()); } 54 54 bool grow(uint32_t delta) WARN_UNUSED_RETURN; 55 JSObject* getFunction(uint32_t); 56 void clearFunction(uint32_t); 57 void setFunction(VM&, uint32_t, WebAssemblyFunction*); 58 void setFunction(VM&, uint32_t, WebAssemblyWrapperFunction*); 55 JSValue get(uint32_t); 56 void set(uint32_t, WebAssemblyFunction*); 57 void set(uint32_t, WebAssemblyWrapperFunction*); 58 void set(uint32_t, JSValue); 59 void clear(uint32_t); 59 60 60 61 Wasm::Table* table() { return m_table.ptr(); } … … 67 68 68 69 Ref<Wasm::Table> m_table; 69 MallocPtr<WriteBarrier<JSObject>> m_jsFunctions;70 70 }; 71 71 -
trunk/Source/JavaScriptCore/wasm/js/WebAssemblyModuleRecord.cpp
r245765 r246139 281 281 } 282 282 283 auto expectedType = moduleInformation.tableInformation.type(); 284 auto actualType = table->table()->type(); 285 if (expectedType != actualType) 286 return exception(createJSWebAssemblyLinkError(exec, vm, importFailMessage(import, "Table import", "provided a 'type' that is wrong"))); 287 283 288 // ii. Append v to tables. 284 289 // iii. Append v.[[Table]] to imports. … … 302 307 RELEASE_ASSERT(!moduleInformation.tableInformation.isImport()); 303 308 // We create a Table when it's a Table definition. 304 RefPtr<Wasm::Table> wasmTable = Wasm::Table::tryCreate(moduleInformation.tableInformation.initial(), moduleInformation.tableInformation.maximum() );309 RefPtr<Wasm::Table> wasmTable = Wasm::Table::tryCreate(moduleInformation.tableInformation.initial(), moduleInformation.tableInformation.maximum(), moduleInformation.tableInformation.type()); 305 310 if (!wasmTable) 306 311 return exception(createJSWebAssemblyLinkError(exec, vm, "couldn't create Table")); … … 537 542 // the only type this could be is WebAssemblyFunction. 538 543 RELEASE_ASSERT(wasmFunction); 539 table->set Function(vm,tableIndex, wasmFunction);544 table->set(tableIndex, wasmFunction); 540 545 ++tableIndex; 541 546 continue; 542 547 } 543 548 544 table->set Function(vm,tableIndex,549 table->set(tableIndex, 545 550 WebAssemblyWrapperFunction::create(vm, globalObject, globalObject->webAssemblyWrapperFunctionStructure(), functionImport, functionIndex, m_instance.get(), signatureIndex)); 546 551 ++tableIndex; … … 558 563 vm, globalObject, globalObject->webAssemblyFunctionStructure(), signature.argumentCount(), String(), m_instance.get(), embedderEntrypointCallee, entrypointLoadLocation, signatureIndex); 559 564 560 table->set Function(vm,tableIndex, function);565 table->set(tableIndex, function); 561 566 ++tableIndex; 562 567 } -
trunk/Source/JavaScriptCore/wasm/js/WebAssemblyTableConstructor.cpp
r243051 r246139 59 59 } 60 60 61 Wasm::TableElementType type; 61 62 { 62 63 Identifier elementIdent = Identifier::fromString(&vm, "element"); … … 65 66 String elementString = elementValue.toWTFString(exec); 66 67 RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); 67 if (elementString != "anyfunc") 68 return JSValue::encode(throwException(exec, throwScope, createTypeError(exec, "WebAssembly.Table expects its 'element' field to be the string 'anyfunc'"_s))); 68 if (elementString == "anyfunc") 69 type = Wasm::TableElementType::Funcref; 70 else if (elementString == "anyref") 71 type = Wasm::TableElementType::Anyref; 72 else 73 return JSValue::encode(throwException(exec, throwScope, createTypeError(exec, "WebAssembly.Table expects its 'element' field to be the string 'anyfunc' or 'anyref'"_s))); 69 74 } 70 75 … … 91 96 } 92 97 93 RefPtr<Wasm::Table> wasmTable = Wasm::Table::tryCreate(initial, maximum );98 RefPtr<Wasm::Table> wasmTable = Wasm::Table::tryCreate(initial, maximum, type); 94 99 if (!wasmTable) { 95 100 return JSValue::encode(throwException(exec, throwScope, -
trunk/Source/JavaScriptCore/wasm/js/WebAssemblyTablePrototype.cpp
r245082 r246139 110 110 return JSValue::encode(throwException(exec, throwScope, createRangeError(exec, "WebAssembly.Table.prototype.get expects an integer less than the length of the table"_s))); 111 111 112 if (JSObject* result = table->getFunction(index)) 113 return JSValue::encode(result); 114 return JSValue::encode(jsNull()); 112 return JSValue::encode(table->get(index)); 115 113 } 116 114 … … 124 122 125 123 JSValue value = exec->argument(1); 126 WebAssemblyFunction* wasmFunction;127 WebAssemblyWrapperFunction* wasmWrapperFunction;128 if (!value.isNull() && !isWebAssemblyHostFunction(vm, value, wasmFunction, wasmWrapperFunction))129 return JSValue::encode(throwException(exec, throwScope, createTypeError(exec, "WebAssembly.Table.prototype.set expects the second argument to be null or an instance of WebAssembly.Function"_s)));130 124 131 125 uint32_t index = toNonWrappingUint32(exec, exec->argument(0)); … … 135 129 return JSValue::encode(throwException(exec, throwScope, createRangeError(exec, "WebAssembly.Table.prototype.set expects an integer less than the length of the table"_s))); 136 130 137 if (value.isNull()) 138 table->clearFunction(index); 139 else { 140 ASSERT(value.isObject() && isWebAssemblyHostFunction(vm, jsCast<JSObject*>(value), wasmFunction, wasmWrapperFunction)); 141 ASSERT(!!wasmFunction || !!wasmWrapperFunction); 142 if (wasmFunction) 143 table->setFunction(vm, index, wasmFunction); 144 else 145 table->setFunction(vm, index, wasmWrapperFunction); 146 } 131 if (table->table()->asFuncrefTable()) { 132 WebAssemblyFunction* wasmFunction; 133 WebAssemblyWrapperFunction* wasmWrapperFunction; 134 if (!value.isNull() && !isWebAssemblyHostFunction(vm, value, wasmFunction, wasmWrapperFunction)) 135 return JSValue::encode(throwException(exec, throwScope, createTypeError(exec, "WebAssembly.Table.prototype.set expects the second argument to be null or an instance of WebAssembly.Function"_s))); 136 137 if (value.isNull()) 138 table->clear(index); 139 else { 140 ASSERT(value.isObject() && isWebAssemblyHostFunction(vm, jsCast<JSObject*>(value), wasmFunction, wasmWrapperFunction)); 141 ASSERT(!!wasmFunction || !!wasmWrapperFunction); 142 if (wasmFunction) 143 table->set(index, wasmFunction); 144 else 145 table->set(index, wasmWrapperFunction); 146 } 147 } else 148 table->set(index, value); 147 149 148 150 return JSValue::encode(jsUndefined()); -
trunk/Source/JavaScriptCore/wasm/wasm.json
r245496 r246139 19 19 "value_type": ["i32", "i64", "f32", "f64", "anyref"], 20 20 "block_type": ["i32", "i64", "f32", "f64", "void", "anyref"], 21 "elem_type": ["anyfunc" ],21 "elem_type": ["anyfunc","anyref"], 22 22 "external_kind": { 23 23 "Function": { "type": "uint8", "value": 0 }, … … 67 67 "get_global": { "category": "special", "value": 35, "return": ["any"], "parameter": [], "immediate": [{"name": "global_index", "type": "varuint32"}], "description": "read a global variable" }, 68 68 "set_global": { "category": "special", "value": 36, "return": [], "parameter": ["any"], "immediate": [{"name": "global_index", "type": "varuint32"}], "description": "write a global variable" }, 69 "table.get": { "category": "special", "value": 37, "return": ["anyref"], "parameter": ["i32"], "immediate": [], "description": "get a table value" }, 70 "table.set": { "category": "special", "value": 38, "return": [], "parameter": ["i32", "anyref"], "immediate": [], "description": "set a table value" }, 69 71 "call": { "category": "call", "value": 16, "return": ["call"], "parameter": ["call"], "immediate": [{"name": "function_index", "type": "varuint32"}], "description": "call a function by its index" }, 70 72 "call_indirect": { "category": "call", "value": 17, "return": ["call"], "parameter": ["call"], "immediate": [{"name": "type_index", "type": "varuint32"}, {"name": "reserved", "type": "varuint1"}], "description": "call a function indirect with an expected signature" },
Note: See TracChangeset
for help on using the changeset viewer.