summaryrefslogtreecommitdiff
path: root/deps/v8/src/asmjs
diff options
context:
space:
mode:
authorMichaƫl Zasso <targos@protonmail.com>2017-09-12 11:34:59 +0200
committerAnna Henningsen <anna@addaleax.net>2017-09-13 16:15:18 +0200
commitd82e1075dbc2cec2d6598ade10c1f43805f690fd (patch)
treeccd242b9b491dfc341d1099fe11b0ef528839877 /deps/v8/src/asmjs
parentb4b7ac6ae811b2b5a3082468115dfb5a5246fe3f (diff)
downloadandroid-node-v8-d82e1075dbc2cec2d6598ade10c1f43805f690fd.tar.gz
android-node-v8-d82e1075dbc2cec2d6598ade10c1f43805f690fd.tar.bz2
android-node-v8-d82e1075dbc2cec2d6598ade10c1f43805f690fd.zip
deps: update V8 to 6.1.534.36
PR-URL: https://github.com/nodejs/node/pull/14730 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Ali Ijaz Sheikh <ofrobots@google.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Diffstat (limited to 'deps/v8/src/asmjs')
-rw-r--r--deps/v8/src/asmjs/OWNERS2
-rw-r--r--deps/v8/src/asmjs/asm-js.cc33
-rw-r--r--deps/v8/src/asmjs/asm-parser.cc68
-rw-r--r--deps/v8/src/asmjs/asm-parser.h57
-rw-r--r--deps/v8/src/asmjs/asm-scanner.cc5
-rw-r--r--deps/v8/src/asmjs/asm-scanner.h2
-rw-r--r--deps/v8/src/asmjs/asm-types.cc1
7 files changed, 105 insertions, 63 deletions
diff --git a/deps/v8/src/asmjs/OWNERS b/deps/v8/src/asmjs/OWNERS
index 4f54661aeb..e40f5b57f3 100644
--- a/deps/v8/src/asmjs/OWNERS
+++ b/deps/v8/src/asmjs/OWNERS
@@ -6,3 +6,5 @@ clemensh@chromium.org
mtrofin@chromium.org
rossberg@chromium.org
titzer@chromium.org
+
+# COMPONENT: Blink>JavaScript>WebAssembly
diff --git a/deps/v8/src/asmjs/asm-js.cc b/deps/v8/src/asmjs/asm-js.cc
index 516bce2543..fb257e316e 100644
--- a/deps/v8/src/asmjs/asm-js.cc
+++ b/deps/v8/src/asmjs/asm-js.cc
@@ -4,8 +4,6 @@
#include "src/asmjs/asm-js.h"
-#include "src/api-natives.h"
-#include "src/api.h"
#include "src/asmjs/asm-names.h"
#include "src/asmjs/asm-parser.h"
#include "src/assert-scope.h"
@@ -17,7 +15,8 @@
#include "src/handles.h"
#include "src/isolate.h"
#include "src/objects-inl.h"
-#include "src/objects.h"
+#include "src/parsing/scanner-character-streams.h"
+#include "src/parsing/scanner.h"
#include "src/wasm/module-decoder.h"
#include "src/wasm/wasm-js.h"
@@ -54,12 +53,12 @@ bool IsStdlibMemberValid(Isolate* isolate, Handle<JSReceiver> stdlib,
bool* is_typed_array) {
switch (member) {
case wasm::AsmJsParser::StandardMember::kInfinity: {
- Handle<Name> name = isolate->factory()->infinity_string();
+ Handle<Name> name = isolate->factory()->Infinity_string();
Handle<Object> value = JSReceiver::GetDataProperty(stdlib, name);
return value->IsNumber() && std::isinf(value->Number());
}
case wasm::AsmJsParser::StandardMember::kNaN: {
- Handle<Name> name = isolate->factory()->nan_string();
+ Handle<Name> name = isolate->factory()->NaN_string();
Handle<Object> value = JSReceiver::GetDataProperty(stdlib, name);
return value->IsNaN();
}
@@ -105,7 +104,6 @@ bool IsStdlibMemberValid(Isolate* isolate, Handle<JSReceiver> stdlib,
#undef STDLIB_ARRAY_TYPE
}
UNREACHABLE();
- return false;
}
void Report(Handle<Script> script, int position, Vector<const char> text,
@@ -193,9 +191,11 @@ MaybeHandle<FixedArray> AsmJs::CompileAsmViaWasm(CompilationInfo* info) {
Zone* compile_zone = info->zone();
Zone translate_zone(info->isolate()->allocator(), ZONE_NAME);
- wasm::AsmJsParser parser(info->isolate(), &translate_zone, info->script(),
- info->literal()->start_position(),
- info->literal()->end_position());
+ std::unique_ptr<Utf16CharacterStream> stream(ScannerStream::For(
+ handle(String::cast(info->script()->source())),
+ info->literal()->start_position(), info->literal()->end_position()));
+ uintptr_t stack_limit = info->isolate()->stack_guard()->real_climit();
+ wasm::AsmJsParser parser(&translate_zone, stack_limit, std::move(stream));
if (!parser.Run()) {
DCHECK(!info->isolate()->has_pending_exception());
ReportCompilationFailure(info->script(), parser.failure_location(),
@@ -277,7 +277,7 @@ MaybeHandle<Object> AsmJs::InstantiateAsmWasm(Isolate* isolate,
ReportInstantiationFailure(script, position, "Requires standard library");
return MaybeHandle<Object>();
}
- int member_id = Smi::cast(stdlib_uses->get(i))->value();
+ int member_id = Smi::ToInt(stdlib_uses->get(i));
wasm::AsmJsParser::StandardMember member =
static_cast<wasm::AsmJsParser::StandardMember>(member_id);
if (!IsStdlibMemberValid(isolate, stdlib, member,
@@ -287,16 +287,6 @@ MaybeHandle<Object> AsmJs::InstantiateAsmWasm(Isolate* isolate,
}
}
- // Create the ffi object for foreign functions {"": foreign}.
- Handle<JSObject> ffi_object;
- if (!foreign.is_null()) {
- Handle<JSFunction> object_function = Handle<JSFunction>(
- isolate->native_context()->object_function(), isolate);
- ffi_object = isolate->factory()->NewJSObject(object_function);
- JSObject::AddProperty(ffi_object, isolate->factory()->empty_string(),
- foreign, NONE);
- }
-
// Check that a valid heap buffer is provided if required.
if (stdlib_use_of_typed_array_present) {
if (memory.is_null()) {
@@ -314,8 +304,9 @@ MaybeHandle<Object> AsmJs::InstantiateAsmWasm(Isolate* isolate,
wasm::ErrorThrower thrower(isolate, "AsmJs::Instantiate");
MaybeHandle<Object> maybe_module_object =
- wasm::SyncInstantiate(isolate, &thrower, module, ffi_object, memory);
+ wasm::SyncInstantiate(isolate, &thrower, module, foreign, memory);
if (maybe_module_object.is_null()) {
+ DCHECK(!isolate->has_pending_exception());
thrower.Reset(); // Ensure exceptions do not propagate.
ReportInstantiationFailure(script, position, "Internal wasm failure");
return MaybeHandle<Object>();
diff --git a/deps/v8/src/asmjs/asm-parser.cc b/deps/v8/src/asmjs/asm-parser.cc
index 51b8f7bbc2..1e5f7d5dc4 100644
--- a/deps/v8/src/asmjs/asm-parser.cc
+++ b/deps/v8/src/asmjs/asm-parser.cc
@@ -11,9 +11,8 @@
#include "src/asmjs/asm-js.h"
#include "src/asmjs/asm-types.h"
-#include "src/objects-inl.h"
-#include "src/objects.h"
-#include "src/parsing/scanner-character-streams.h"
+#include "src/base/optional.h"
+#include "src/objects-inl.h" // TODO(mstarzinger): Temporary cycle breaker.
#include "src/parsing/scanner.h"
#include "src/wasm/wasm-opcodes.h"
@@ -68,16 +67,16 @@ namespace wasm {
#define TOK(name) AsmJsScanner::kToken_##name
-AsmJsParser::AsmJsParser(Isolate* isolate, Zone* zone, Handle<Script> script,
- int start, int end)
+AsmJsParser::AsmJsParser(Zone* zone, uintptr_t stack_limit,
+ std::unique_ptr<Utf16CharacterStream> stream)
: zone_(zone),
module_builder_(new (zone) WasmModuleBuilder(zone)),
return_type_(nullptr),
- stack_limit_(isolate->stack_guard()->real_climit()),
+ stack_limit_(stack_limit),
global_var_info_(zone),
local_var_info_(zone),
failed_(false),
- failure_location_(start),
+ failure_location_(kNoSourcePosition),
stdlib_name_(kTokenNone),
foreign_name_(kTokenNone),
heap_name_(kTokenNone),
@@ -89,9 +88,6 @@ AsmJsParser::AsmJsParser(Isolate* isolate, Zone* zone, Handle<Script> script,
pending_label_(0),
global_imports_(zone) {
InitializeStdlibTypes();
- Handle<String> source(String::cast(script->source()), isolate);
- std::unique_ptr<Utf16CharacterStream> stream(
- ScannerStream::For(source, start, end));
scanner_.SetStream(std::move(stream));
}
@@ -144,8 +140,8 @@ void AsmJsParser::InitializeStdlibTypes() {
stdlib_fround_ = AsmType::FroundType(zone());
}
-FunctionSig* AsmJsParser::ConvertSignature(
- AsmType* return_type, const std::vector<AsmType*>& params) {
+FunctionSig* AsmJsParser::ConvertSignature(AsmType* return_type,
+ const ZoneVector<AsmType*>& params) {
FunctionSig::Builder sig_builder(
zone(), !return_type->IsA(AsmType::Void()) ? 1 : 0, params.size());
for (auto param : params) {
@@ -215,7 +211,6 @@ wasm::AsmJsParser::VarInfo* AsmJsParser::GetVarInfo(
return &local_var_info_[index];
}
UNREACHABLE();
- return nullptr;
}
uint32_t AsmJsParser::VarIndex(VarInfo* info) {
@@ -348,9 +343,15 @@ void AsmJsParser::ValidateModule() {
if (info.kind == VarKind::kTable && !info.function_defined) {
FAIL("Undefined function table");
}
+ if (info.kind == VarKind::kImportedFunction && !info.function_defined) {
+ // For imported functions without a single call site, we insert a dummy
+ // import here to preserve the fact that there actually was an import.
+ FunctionSig* void_void_sig = FunctionSig::Builder(zone(), 0, 0).Build();
+ module_builder_->AddImport(info.import->function_name, void_void_sig);
+ }
}
- // Add start function to init things.
+ // Add start function to initialize things.
WasmFunctionBuilder* start = module_builder_->AddFunction();
module_builder_->MarkStartFunction(start);
for (auto& global_import : global_imports_) {
@@ -725,9 +726,9 @@ void AsmJsParser::ValidateFunction() {
int start_position = static_cast<int>(scanner_.Position());
current_function_builder_->SetAsmFunctionStartPosition(start_position);
- std::vector<AsmType*> params;
+ CachedVector<AsmType*> params(cached_asm_type_p_vectors_);
ValidateFunctionParams(&params);
- std::vector<ValueType> locals;
+ CachedVector<ValueType> locals(cached_valuetype_vectors_);
ValidateFunctionLocals(params.size(), &locals);
function_temp_locals_offset_ = static_cast<uint32_t>(
@@ -787,13 +788,14 @@ void AsmJsParser::ValidateFunction() {
}
// 6.4 ValidateFunction
-void AsmJsParser::ValidateFunctionParams(std::vector<AsmType*>* params) {
+void AsmJsParser::ValidateFunctionParams(ZoneVector<AsmType*>* params) {
// TODO(bradnelson): Do this differently so that the scanner doesn't need to
// have a state transition that needs knowledge of how the scanner works
// inside.
scanner_.EnterLocalScope();
EXPECT_TOKEN('(');
- std::vector<AsmJsScanner::token_t> function_parameters;
+ CachedVector<AsmJsScanner::token_t> function_parameters(
+ cached_token_t_vectors_);
while (!failed_ && !Peek(')')) {
if (!scanner_.IsLocal()) {
FAIL("Expected parameter name");
@@ -847,8 +849,8 @@ void AsmJsParser::ValidateFunctionParams(std::vector<AsmType*>* params) {
}
// 6.4 ValidateFunction - locals
-void AsmJsParser::ValidateFunctionLocals(
- size_t param_count, std::vector<ValueType>* locals) {
+void AsmJsParser::ValidateFunctionLocals(size_t param_count,
+ ZoneVector<ValueType>* locals) {
// Local Variables.
while (Peek(TOK(var))) {
scanner_.EnterLocalScope();
@@ -1262,7 +1264,7 @@ void AsmJsParser::SwitchStatement() {
Begin(pending_label_);
pending_label_ = 0;
// TODO(bradnelson): Make less weird.
- std::vector<int32_t> cases;
+ CachedVector<int32_t> cases(cached_int_vectors_);
GatherCases(&cases);
EXPECT_TOKEN('{');
size_t count = cases.size() + 1;
@@ -1398,7 +1400,6 @@ AsmType* AsmJsParser::Identifier() {
return info->type;
}
UNREACHABLE();
- return nullptr;
}
// 6.8.4 CallExpression
@@ -1677,7 +1678,7 @@ AsmType* AsmJsParser::MultiplicativeExpression() {
}
} else if (Check('/')) {
AsmType* b;
- RECURSEn(b = MultiplicativeExpression());
+ RECURSEn(b = UnaryExpression());
if (a->IsA(AsmType::DoubleQ()) && b->IsA(AsmType::DoubleQ())) {
current_function_builder_->Emit(kExprF64Div);
a = AsmType::Double();
@@ -1695,7 +1696,7 @@ AsmType* AsmJsParser::MultiplicativeExpression() {
}
} else if (Check('%')) {
AsmType* b;
- RECURSEn(b = MultiplicativeExpression());
+ RECURSEn(b = UnaryExpression());
if (a->IsA(AsmType::DoubleQ()) && b->IsA(AsmType::DoubleQ())) {
current_function_builder_->Emit(kExprF64Mod);
a = AsmType::Double();
@@ -2014,8 +2015,7 @@ AsmType* AsmJsParser::ValidateCall() {
// both cases we might be seeing the {function_name} for the first time and
// hence allocate a {VarInfo} here, all subsequent uses of the same name then
// need to match the information stored at this point.
- // TODO(mstarzinger): Consider using Chromiums base::Optional instead.
- std::unique_ptr<TemporaryVariableScope> tmp;
+ base::Optional<TemporaryVariableScope> tmp;
if (Check('[')) {
RECURSEn(EqualityExpression());
EXPECT_TOKENn('&');
@@ -2023,7 +2023,7 @@ AsmType* AsmJsParser::ValidateCall() {
if (!CheckForUnsigned(&mask)) {
FAILn("Expected mask literal");
}
- if (!base::bits::IsPowerOfTwo32(mask + 1)) {
+ if (!base::bits::IsPowerOfTwo(mask + 1)) {
FAILn("Expected power of 2 mask");
}
current_function_builder_->EmitI32Const(mask);
@@ -2050,8 +2050,8 @@ AsmType* AsmJsParser::ValidateCall() {
current_function_builder_->EmitI32Const(function_info->index);
current_function_builder_->Emit(kExprI32Add);
// We have to use a temporary for the correct order of evaluation.
- tmp.reset(new TemporaryVariableScope(this));
- current_function_builder_->EmitSetLocal(tmp.get()->get());
+ tmp.emplace(this);
+ current_function_builder_->EmitSetLocal(tmp->get());
// The position of function table calls is after the table lookup.
call_pos = static_cast<int>(scanner_.Position());
} else {
@@ -2070,8 +2070,8 @@ AsmType* AsmJsParser::ValidateCall() {
}
// Parse argument list and gather types.
- std::vector<AsmType*> param_types;
- ZoneVector<AsmType*> param_specific_types(zone());
+ CachedVector<AsmType*> param_types(cached_asm_type_p_vectors_);
+ CachedVector<AsmType*> param_specific_types(cached_asm_type_p_vectors_);
EXPECT_TOKENn('(');
while (!failed_ && !Peek(')')) {
AsmType* t;
@@ -2149,10 +2149,12 @@ AsmType* AsmJsParser::ValidateCall() {
auto it = function_info->import->cache.find(sig);
if (it != function_info->import->cache.end()) {
index = it->second;
+ DCHECK(function_info->function_defined);
} else {
index =
module_builder_->AddImport(function_info->import->function_name, sig);
function_info->import->cache[sig] = index;
+ function_info->function_defined = true;
}
current_function_builder_->AddAsmWasmOffset(call_pos, to_number_pos);
current_function_builder_->EmitWithU32V(kExprCallFunction, index);
@@ -2283,7 +2285,7 @@ AsmType* AsmJsParser::ValidateCall() {
}
}
if (function_info->kind == VarKind::kTable) {
- current_function_builder_->EmitGetLocal(tmp.get()->get());
+ current_function_builder_->EmitGetLocal(tmp->get());
current_function_builder_->AddAsmWasmOffset(call_pos, to_number_pos);
current_function_builder_->Emit(kExprCallIndirect);
current_function_builder_->EmitU32V(signature_index);
@@ -2420,7 +2422,7 @@ void AsmJsParser::ScanToClosingParenthesis() {
}
}
-void AsmJsParser::GatherCases(std::vector<int32_t>* cases) {
+void AsmJsParser::GatherCases(ZoneVector<int32_t>* cases) {
size_t start = scanner_.Position();
int depth = 0;
for (;;) {
diff --git a/deps/v8/src/asmjs/asm-parser.h b/deps/v8/src/asmjs/asm-parser.h
index 2f20b4813d..4f880785ef 100644
--- a/deps/v8/src/asmjs/asm-parser.h
+++ b/deps/v8/src/asmjs/asm-parser.h
@@ -5,8 +5,8 @@
#ifndef V8_ASMJS_ASM_PARSER_H_
#define V8_ASMJS_ASM_PARSER_H_
+#include <memory>
#include <string>
-#include <vector>
#include "src/asmjs/asm-scanner.h"
#include "src/asmjs/asm-types.h"
@@ -15,6 +15,9 @@
namespace v8 {
namespace internal {
+
+class Utf16CharacterStream;
+
namespace wasm {
// A custom parser + validator + wasm converter for asm.js:
@@ -46,8 +49,8 @@ class AsmJsParser {
typedef std::unordered_set<StandardMember, std::hash<int>> StdlibSet;
- explicit AsmJsParser(Isolate* isolate, Zone* zone, Handle<Script> script,
- int start, int end);
+ explicit AsmJsParser(Zone* zone, uintptr_t stack_limit,
+ std::unique_ptr<Utf16CharacterStream> stream);
bool Run();
const char* failure_message() const { return failure_message_; }
int failure_location() const { return failure_location_; }
@@ -105,6 +108,41 @@ class AsmJsParser {
// Helper class to make {TempVariable} safe for nesting.
class TemporaryVariableScope;
+ template <typename T>
+ class CachedVectors {
+ public:
+ explicit CachedVectors(Zone* zone) : reusable_vectors_(zone) {}
+
+ Zone* zone() const { return reusable_vectors_.get_allocator().zone(); }
+
+ inline void fill(ZoneVector<T>* vec) {
+ if (reusable_vectors_.empty()) return;
+ reusable_vectors_.back().swap(*vec);
+ reusable_vectors_.pop_back();
+ vec->clear();
+ }
+
+ inline void reuse(ZoneVector<T>* vec) {
+ reusable_vectors_.emplace_back(std::move(*vec));
+ }
+
+ private:
+ ZoneVector<ZoneVector<T>> reusable_vectors_;
+ };
+
+ template <typename T>
+ class CachedVector final : public ZoneVector<T> {
+ public:
+ explicit CachedVector(CachedVectors<T>& cache)
+ : ZoneVector<T>(cache.zone()), cache_(&cache) {
+ cache.fill(this);
+ }
+ ~CachedVector() { cache_->reuse(this); }
+
+ private:
+ CachedVectors<T>* cache_;
+ };
+
Zone* zone_;
AsmJsScanner scanner_;
WasmModuleBuilder* module_builder_;
@@ -115,6 +153,11 @@ class AsmJsParser {
ZoneVector<VarInfo> global_var_info_;
ZoneVector<VarInfo> local_var_info_;
+ CachedVectors<ValueType> cached_valuetype_vectors_{zone_};
+ CachedVectors<AsmType*> cached_asm_type_p_vectors_{zone_};
+ CachedVectors<AsmJsScanner::token_t> cached_token_t_vectors_{zone_};
+ CachedVectors<int32_t> cached_int_vectors_{zone_};
+
int function_temp_locals_offset_;
int function_temp_locals_used_;
int function_temp_locals_depth_;
@@ -267,7 +310,7 @@ class AsmJsParser {
void InitializeStdlibTypes();
FunctionSig* ConvertSignature(AsmType* return_type,
- const std::vector<AsmType*>& params);
+ const ZoneVector<AsmType*>& params);
void ValidateModule(); // 6.1 ValidateModule
void ValidateModuleParameters(); // 6.1 ValidateModule - parameters
@@ -281,9 +324,9 @@ class AsmJsParser {
void ValidateExport(); // 6.2 ValidateExport
void ValidateFunctionTable(); // 6.3 ValidateFunctionTable
void ValidateFunction(); // 6.4 ValidateFunction
- void ValidateFunctionParams(std::vector<AsmType*>* params);
+ void ValidateFunctionParams(ZoneVector<AsmType*>* params);
void ValidateFunctionLocals(size_t param_count,
- std::vector<ValueType>* locals);
+ ZoneVector<ValueType>* locals);
void ValidateStatement(); // 6.5 ValidateStatement
void Block(); // 6.5.1 Block
void ExpressionStatement(); // 6.5.2 ExpressionStatement
@@ -331,7 +374,7 @@ class AsmJsParser {
// Used as part of {SwitchStatement}. Collects all case labels in the current
// switch-statement, then resets the scanner position. This is one piece that
// makes this parser not be a pure single-pass.
- void GatherCases(std::vector<int32_t>* cases);
+ void GatherCases(ZoneVector<int32_t>* cases);
};
} // namespace wasm
diff --git a/deps/v8/src/asmjs/asm-scanner.cc b/deps/v8/src/asmjs/asm-scanner.cc
index 14b07306fd..a1e2b05c9d 100644
--- a/deps/v8/src/asmjs/asm-scanner.cc
+++ b/deps/v8/src/asmjs/asm-scanner.cc
@@ -46,6 +46,10 @@ AsmJsScanner::AsmJsScanner()
#undef V
}
+// Destructor of unique_ptr<T> requires complete declaration of T, we only want
+// to include the necessary declaration here instead of the header file.
+AsmJsScanner::~AsmJsScanner() {}
+
void AsmJsScanner::SetStream(std::unique_ptr<Utf16CharacterStream> stream) {
stream_ = std::move(stream);
Next();
@@ -208,7 +212,6 @@ std::string AsmJsScanner::Name(token_t token) const {
break;
}
UNREACHABLE();
- return "{unreachable}";
}
#endif
diff --git a/deps/v8/src/asmjs/asm-scanner.h b/deps/v8/src/asmjs/asm-scanner.h
index d519862a83..13ffb21bc7 100644
--- a/deps/v8/src/asmjs/asm-scanner.h
+++ b/deps/v8/src/asmjs/asm-scanner.h
@@ -32,6 +32,8 @@ class V8_EXPORT_PRIVATE AsmJsScanner {
typedef int32_t token_t;
AsmJsScanner();
+ ~AsmJsScanner();
+
// Pick the stream to parse (must be called before anything else).
void SetStream(std::unique_ptr<Utf16CharacterStream> stream);
diff --git a/deps/v8/src/asmjs/asm-types.cc b/deps/v8/src/asmjs/asm-types.cc
index 79c43a370b..3deb588e4f 100644
--- a/deps/v8/src/asmjs/asm-types.cc
+++ b/deps/v8/src/asmjs/asm-types.cc
@@ -69,7 +69,6 @@ bool AsmType::IsA(AsmType* that) {
}
UNREACHABLE();
- return that == this;
}
int32_t AsmType::ElementSizeInBytes() {