| // Copyright 2023 the V8 project authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "src/wasm/well-known-imports.h" |
| |
| namespace v8::internal::wasm { |
| |
| const char* WellKnownImportName(WellKnownImport wki) { |
| switch (wki) { |
| // Generic: |
| case WellKnownImport::kUninstantiated: |
| return "uninstantiated"; |
| case WellKnownImport::kGeneric: |
| return "generic"; |
| case WellKnownImport::kLinkError: |
| return "LinkError"; |
| |
| // DataView methods: |
| case WellKnownImport::kDataViewGetBigInt64: |
| return "DataView.getBigInt64"; |
| case WellKnownImport::kDataViewGetBigUint64: |
| return "DataView.getBigUint64"; |
| case WellKnownImport::kDataViewGetFloat32: |
| return "DataView.getFloat32"; |
| case WellKnownImport::kDataViewGetFloat64: |
| return "DataView.getFloat64"; |
| case WellKnownImport::kDataViewGetInt8: |
| return "DataView.getInt8"; |
| case WellKnownImport::kDataViewGetInt16: |
| return "DataView.getInt16"; |
| case WellKnownImport::kDataViewGetInt32: |
| return "DataView.getInt32"; |
| case WellKnownImport::kDataViewGetUint8: |
| return "DataView.getUint8"; |
| case WellKnownImport::kDataViewGetUint16: |
| return "DataView.getUint16"; |
| case WellKnownImport::kDataViewGetUint32: |
| return "DataView.getUint32"; |
| case WellKnownImport::kDataViewSetBigInt64: |
| return "DataView.setBigInt64"; |
| case WellKnownImport::kDataViewSetBigUint64: |
| return "DataView.setBigUint64"; |
| case WellKnownImport::kDataViewSetFloat32: |
| return "DataView.setFloat32"; |
| case WellKnownImport::kDataViewSetFloat64: |
| return "DataView.setFloat64"; |
| case WellKnownImport::kDataViewSetInt8: |
| return "DataView.setInt8"; |
| case WellKnownImport::kDataViewSetInt16: |
| return "DataView.setInt16"; |
| case WellKnownImport::kDataViewSetInt32: |
| return "DataView.setInt32"; |
| case WellKnownImport::kDataViewSetUint8: |
| return "DataView.setUint8"; |
| case WellKnownImport::kDataViewSetUint16: |
| return "DataView.setUint16"; |
| case WellKnownImport::kDataViewSetUint32: |
| return "DataView.setUint32"; |
| case WellKnownImport::kDataViewByteLength: |
| return "DataView.byteLength"; |
| |
| // Math functions. |
| case WellKnownImport::kMathF64Acos: |
| return "Math.acos"; |
| case WellKnownImport::kMathF64Asin: |
| return "Math.asin"; |
| case WellKnownImport::kMathF64Atan: |
| return "Math.atan"; |
| case WellKnownImport::kMathF64Atan2: |
| return "Math.atan2"; |
| case WellKnownImport::kMathF64Cos: |
| return "Math.cos"; |
| case WellKnownImport::kMathF64Sin: |
| return "Math.sin"; |
| case WellKnownImport::kMathF64Tan: |
| return "Math.tan"; |
| case WellKnownImport::kMathF64Exp: |
| return "Math.exp"; |
| case WellKnownImport::kMathF64Log: |
| return "Math.log"; |
| case WellKnownImport::kMathF64Pow: |
| return "Math.pow"; |
| case WellKnownImport::kMathF64Sqrt: |
| return "Math.sqrt"; |
| |
| // String-related functions: |
| case WellKnownImport::kDoubleToString: |
| return "DoubleToString"; |
| case WellKnownImport::kIntToString: |
| return "IntToString"; |
| case WellKnownImport::kParseFloat: |
| return "ParseFloat"; |
| case WellKnownImport::kStringIndexOf: |
| case WellKnownImport::kStringIndexOfImported: |
| return "String.indexOf"; |
| case WellKnownImport::kStringToLocaleLowerCaseStringref: |
| return "String.toLocaleLowerCase"; |
| case WellKnownImport::kStringToLowerCaseStringref: |
| case WellKnownImport::kStringToLowerCaseImported: |
| return "String.toLowerCase"; |
| |
| // JS String Builtins: |
| case WellKnownImport::kStringCast: |
| return "js-string:cast"; |
| case WellKnownImport::kStringCharCodeAt: |
| return "js-string:charCodeAt"; |
| case WellKnownImport::kStringCodePointAt: |
| return "js-string:codePointAt"; |
| case WellKnownImport::kStringCompare: |
| return "js-string:compare"; |
| case WellKnownImport::kStringConcat: |
| return "js-string:concat"; |
| case WellKnownImport::kStringEquals: |
| return "js-string:equals"; |
| case WellKnownImport::kStringFromCharCode: |
| return "js-string:fromCharCode"; |
| case WellKnownImport::kStringFromCodePoint: |
| return "js-string:fromCodePoint"; |
| case WellKnownImport::kStringFromUtf8Array: |
| return "text-decoder:decodeStringFromUTF8Array"; |
| case WellKnownImport::kStringFromWtf16Array: |
| return "js-string:fromCharCodeArray"; |
| case WellKnownImport::kStringIntoUtf8Array: |
| return "text-encoder:encodeStringIntoUTF8Array"; |
| case WellKnownImport::kStringToUtf8Array: |
| return "text-encoder:encodeStringToUTF8Array"; |
| case WellKnownImport::kStringLength: |
| return "js-string:length"; |
| case WellKnownImport::kStringMeasureUtf8: |
| return "text-encoder:measureStringAsUTF8"; |
| case WellKnownImport::kStringSubstring: |
| return "js-string:substring"; |
| case WellKnownImport::kStringTest: |
| return "js-string:test"; |
| case WellKnownImport::kStringToWtf16Array: |
| return "js-string:intoCharCodeArray"; |
| |
| // Fast API Call: |
| case WellKnownImport::kFastAPICall: |
| return "fast API call"; |
| } |
| } |
| |
| WellKnownImportsList::UpdateResult WellKnownImportsList::Update( |
| base::Vector<WellKnownImport> entries) { |
| DCHECK_EQ(entries.size(), static_cast<size_t>(size_)); |
| for (size_t i = 0; i < entries.size(); i++) { |
| WellKnownImport entry = entries[i]; |
| DCHECK(entry != WellKnownImport::kUninstantiated); |
| WellKnownImport old = statuses_[i].load(std::memory_order_relaxed); |
| if (old == WellKnownImport::kGeneric) continue; |
| if (old == entry) continue; |
| if (old == WellKnownImport::kUninstantiated) { |
| statuses_[i].store(entry, std::memory_order_relaxed); |
| } else { |
| // To avoid having to clear Turbofan code multiple times, we give up |
| // entirely once the first problem occurs. |
| // This is a heuristic; we could also choose to make finer-grained |
| // decisions and only set {statuses_[i] = kGeneric}. We expect that |
| // this case won't ever happen for production modules, so guarding |
| // against pathological cases seems more important than being lenient |
| // towards almost-well-behaved modules. |
| for (size_t j = 0; j < entries.size(); j++) { |
| statuses_[j].store(WellKnownImport::kGeneric, |
| std::memory_order_relaxed); |
| } |
| return UpdateResult::kFoundIncompatibility; |
| } |
| } |
| return UpdateResult::kOK; |
| } |
| |
| void WellKnownImportsList::Initialize( |
| base::Vector<const WellKnownImport> entries) { |
| DCHECK_EQ(entries.size(), static_cast<size_t>(size_)); |
| for (size_t i = 0; i < entries.size(); i++) { |
| DCHECK_EQ(WellKnownImport::kUninstantiated, |
| statuses_[i].load(std::memory_order_relaxed)); |
| statuses_[i].store(entries[i], std::memory_order_relaxed); |
| } |
| } |
| |
| } // namespace v8::internal::wasm |