Commit b1cfa644 authored by bradnelson's avatar bradnelson Committed by Commit bot

[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}
parent e8188a2d
......@@ -20,25 +20,31 @@
#include "src/globals.h"
#include "src/messages.h"
#include "src/utils.h"
#define FAIL_LOCATION(location, msg) \
do { \
Handle<String> message(isolate_->factory()->InternalizeOneByteString( \
STATIC_CHAR_VECTOR(msg))); \
error_message_ = MessageHandler::MakeMessageObject( \
isolate_, MessageTemplate::kAsmJsInvalid, (location), message, \
Handle<JSArray>::null()); \
error_message_->set_error_level(v8::Isolate::kMessageWarning); \
message_location_ = *(location); \
return AsmType::None(); \
#include "src/vector.h"
#define FAIL_LOCATION_RAW(location, msg) \
do { \
Handle<String> message( \
isolate_->factory()->InternalizeOneByteString(msg)); \
error_message_ = MessageHandler::MakeMessageObject( \
isolate_, MessageTemplate::kAsmJsInvalid, (location), message, \
Handle<JSArray>::null()); \
error_message_->set_error_level(v8::Isolate::kMessageWarning); \
message_location_ = *(location); \
return AsmType::None(); \
} while (false)
#define FAIL(node, msg) \
#define FAIL_RAW(node, msg) \
do { \
MessageLocation location(script_, node->position(), node->position()); \
FAIL_LOCATION(&location, msg); \
FAIL_LOCATION_RAW(&location, msg); \
} 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) \
do { \
if (GetCurrentStackPosition() < stack_limit_) { \
......@@ -530,6 +536,10 @@ AsmTyper::StandardMember AsmTyper::VariableAsStandardMember(Variable* var) {
return member;
}
AsmType* AsmTyper::FailWithMessage(const char* text) {
FAIL_RAW(root_, OneByteVector(text));
}
bool AsmTyper::Validate() {
return ValidateBeforeFunctionsPhase() &&
!AsmType::None()->IsExactly(ValidateModuleFunctions(root_)) &&
......
......@@ -86,6 +86,10 @@ class AsmTyper final {
AsmType* TypeOf(Variable* v) const;
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;
StdlibSet StdlibUses() const { return stdlib_uses_; }
......
......@@ -67,6 +67,7 @@ class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> {
script_(script),
typer_(typer),
typer_failed_(false),
typer_finished_(false),
breakable_blocks_(zone),
foreign_variables_(zone),
init_function_(nullptr),
......@@ -122,6 +123,10 @@ class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> {
if (HasStackOverflow()) {
return false;
}
if (!typer_finished_) {
typer_->FailWithMessage("Module missing export section.");
typer_failed_ = true;
}
if (typer_failed_) {
return false;
}
......@@ -322,10 +327,16 @@ class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> {
void VisitReturnStatement(ReturnStatement* stmt) {
if (scope_ == kModuleScope) {
if (typer_finished_) {
typer_->FailWithMessage("Module has multiple returns.");
typer_failed_ = true;
return;
}
if (!typer_->ValidateAfterFunctionsPhase()) {
typer_failed_ = true;
return;
}
typer_finished_ = true;
scope_ = kExportScope;
RECURSE(Visit(stmt->expression()));
scope_ = kModuleScope;
......@@ -1947,6 +1958,7 @@ class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> {
Handle<Script> script_;
AsmTyper* typer_;
bool typer_failed_;
bool typer_finished_;
ZoneVector<std::pair<BreakableStatement*, bool>> breakable_blocks_;
ZoneVector<ForeignVariable> foreign_variables_;
WasmFunctionBuilder* init_function_;
......
// 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);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment