[wasm][asm.js] Ensure final validation phase runs.
Asm.js modules missing exports fail to run the last phase of validation. Adding an explicit check for this. BUG=676573 R=titzer@chromium.org,aseemgarg@chromium.org Review-Url: https://codereview.chromium.org/2620893002 Cr-Commit-Position: refs/heads/master@{#42191}
This commit is contained in:
parent
e8188a2d99
commit
b1cfa6448c
@ -20,25 +20,31 @@
|
|||||||
#include "src/globals.h"
|
#include "src/globals.h"
|
||||||
#include "src/messages.h"
|
#include "src/messages.h"
|
||||||
#include "src/utils.h"
|
#include "src/utils.h"
|
||||||
|
#include "src/vector.h"
|
||||||
|
|
||||||
#define FAIL_LOCATION(location, msg) \
|
#define FAIL_LOCATION_RAW(location, msg) \
|
||||||
do { \
|
do { \
|
||||||
Handle<String> message(isolate_->factory()->InternalizeOneByteString( \
|
Handle<String> message( \
|
||||||
STATIC_CHAR_VECTOR(msg))); \
|
isolate_->factory()->InternalizeOneByteString(msg)); \
|
||||||
error_message_ = MessageHandler::MakeMessageObject( \
|
error_message_ = MessageHandler::MakeMessageObject( \
|
||||||
isolate_, MessageTemplate::kAsmJsInvalid, (location), message, \
|
isolate_, MessageTemplate::kAsmJsInvalid, (location), message, \
|
||||||
Handle<JSArray>::null()); \
|
Handle<JSArray>::null()); \
|
||||||
error_message_->set_error_level(v8::Isolate::kMessageWarning); \
|
error_message_->set_error_level(v8::Isolate::kMessageWarning); \
|
||||||
message_location_ = *(location); \
|
message_location_ = *(location); \
|
||||||
return AsmType::None(); \
|
return AsmType::None(); \
|
||||||
} while (false)
|
} while (false)
|
||||||
|
|
||||||
#define FAIL(node, msg) \
|
#define FAIL_RAW(node, msg) \
|
||||||
do { \
|
do { \
|
||||||
MessageLocation location(script_, node->position(), node->position()); \
|
MessageLocation location(script_, node->position(), node->position()); \
|
||||||
FAIL_LOCATION(&location, msg); \
|
FAIL_LOCATION_RAW(&location, msg); \
|
||||||
} while (false)
|
} while (false)
|
||||||
|
|
||||||
|
#define FAIL_LOCATION(location, msg) \
|
||||||
|
FAIL_LOCATION_RAW(location, STATIC_CHAR_VECTOR(msg))
|
||||||
|
|
||||||
|
#define FAIL(node, msg) FAIL_RAW(node, STATIC_CHAR_VECTOR(msg))
|
||||||
|
|
||||||
#define RECURSE(call) \
|
#define RECURSE(call) \
|
||||||
do { \
|
do { \
|
||||||
if (GetCurrentStackPosition() < stack_limit_) { \
|
if (GetCurrentStackPosition() < stack_limit_) { \
|
||||||
@ -530,6 +536,10 @@ AsmTyper::StandardMember AsmTyper::VariableAsStandardMember(Variable* var) {
|
|||||||
return member;
|
return member;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AsmType* AsmTyper::FailWithMessage(const char* text) {
|
||||||
|
FAIL_RAW(root_, OneByteVector(text));
|
||||||
|
}
|
||||||
|
|
||||||
bool AsmTyper::Validate() {
|
bool AsmTyper::Validate() {
|
||||||
return ValidateBeforeFunctionsPhase() &&
|
return ValidateBeforeFunctionsPhase() &&
|
||||||
!AsmType::None()->IsExactly(ValidateModuleFunctions(root_)) &&
|
!AsmType::None()->IsExactly(ValidateModuleFunctions(root_)) &&
|
||||||
|
@ -86,6 +86,10 @@ class AsmTyper final {
|
|||||||
AsmType* TypeOf(Variable* v) const;
|
AsmType* TypeOf(Variable* v) const;
|
||||||
StandardMember VariableAsStandardMember(Variable* var);
|
StandardMember VariableAsStandardMember(Variable* var);
|
||||||
|
|
||||||
|
// Allow the asm-wasm-builder to trigger failures (for interleaved
|
||||||
|
// validating).
|
||||||
|
AsmType* FailWithMessage(const char* text);
|
||||||
|
|
||||||
typedef std::unordered_set<StandardMember, std::hash<int> > StdlibSet;
|
typedef std::unordered_set<StandardMember, std::hash<int> > StdlibSet;
|
||||||
|
|
||||||
StdlibSet StdlibUses() const { return stdlib_uses_; }
|
StdlibSet StdlibUses() const { return stdlib_uses_; }
|
||||||
|
@ -67,6 +67,7 @@ class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> {
|
|||||||
script_(script),
|
script_(script),
|
||||||
typer_(typer),
|
typer_(typer),
|
||||||
typer_failed_(false),
|
typer_failed_(false),
|
||||||
|
typer_finished_(false),
|
||||||
breakable_blocks_(zone),
|
breakable_blocks_(zone),
|
||||||
foreign_variables_(zone),
|
foreign_variables_(zone),
|
||||||
init_function_(nullptr),
|
init_function_(nullptr),
|
||||||
@ -122,6 +123,10 @@ class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> {
|
|||||||
if (HasStackOverflow()) {
|
if (HasStackOverflow()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (!typer_finished_) {
|
||||||
|
typer_->FailWithMessage("Module missing export section.");
|
||||||
|
typer_failed_ = true;
|
||||||
|
}
|
||||||
if (typer_failed_) {
|
if (typer_failed_) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -322,10 +327,16 @@ class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> {
|
|||||||
|
|
||||||
void VisitReturnStatement(ReturnStatement* stmt) {
|
void VisitReturnStatement(ReturnStatement* stmt) {
|
||||||
if (scope_ == kModuleScope) {
|
if (scope_ == kModuleScope) {
|
||||||
|
if (typer_finished_) {
|
||||||
|
typer_->FailWithMessage("Module has multiple returns.");
|
||||||
|
typer_failed_ = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (!typer_->ValidateAfterFunctionsPhase()) {
|
if (!typer_->ValidateAfterFunctionsPhase()) {
|
||||||
typer_failed_ = true;
|
typer_failed_ = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
typer_finished_ = true;
|
||||||
scope_ = kExportScope;
|
scope_ = kExportScope;
|
||||||
RECURSE(Visit(stmt->expression()));
|
RECURSE(Visit(stmt->expression()));
|
||||||
scope_ = kModuleScope;
|
scope_ = kModuleScope;
|
||||||
@ -1947,6 +1958,7 @@ class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> {
|
|||||||
Handle<Script> script_;
|
Handle<Script> script_;
|
||||||
AsmTyper* typer_;
|
AsmTyper* typer_;
|
||||||
bool typer_failed_;
|
bool typer_failed_;
|
||||||
|
bool typer_finished_;
|
||||||
ZoneVector<std::pair<BreakableStatement*, bool>> breakable_blocks_;
|
ZoneVector<std::pair<BreakableStatement*, bool>> breakable_blocks_;
|
||||||
ZoneVector<ForeignVariable> foreign_variables_;
|
ZoneVector<ForeignVariable> foreign_variables_;
|
||||||
WasmFunctionBuilder* init_function_;
|
WasmFunctionBuilder* init_function_;
|
||||||
|
17
test/mjsunit/asm/regress-676573.js
Normal file
17
test/mjsunit/asm/regress-676573.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// Copyright 2017 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.
|
||||||
|
|
||||||
|
function baz() {
|
||||||
|
"use asm";
|
||||||
|
}
|
||||||
|
function B(stdlib, env) {
|
||||||
|
"use asm";
|
||||||
|
var x = env.foo | 0;
|
||||||
|
}
|
||||||
|
var bar = {
|
||||||
|
get foo() {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
bar.__defineGetter__('foo', function() { return baz(); });
|
||||||
|
B(this, bar);
|
Loading…
Reference in New Issue
Block a user