Hooking up asm-wasm conversion.
Directs 'use asm' traffic through asm-wasm conversion when --validate-asm is passed. Adds a builtin that handles the fallback to JS. BUG= https://bugs.chromium.org/p/v8/issues/detail?id=4203 TEST=asm-wasm R=mstarzinger@chromium.org,titzer@chromium.org LOG=N Review-Url: https://codereview.chromium.org/2057403003 Cr-Commit-Position: refs/heads/master@{#37470}
This commit is contained in:
parent
d781b95619
commit
f20323dce2
29
BUILD.gn
29
BUILD.gn
@ -628,7 +628,9 @@ action("run_mksnapshot") {
|
||||
|
||||
action("v8_dump_build_config") {
|
||||
script = "tools/testrunner/utils/dump_build_config.py"
|
||||
outputs = [ "$root_out_dir/v8_build_config.json" ]
|
||||
outputs = [
|
||||
"$root_out_dir/v8_build_config.json",
|
||||
]
|
||||
args = [
|
||||
rebase_path("$root_out_dir/v8_build_config.json", root_build_dir),
|
||||
"dcheck_always_on=$dcheck_always_on",
|
||||
@ -642,10 +644,9 @@ action("v8_dump_build_config") {
|
||||
"v8_enable_i18n_support=$v8_enable_i18n_support",
|
||||
"v8_target_cpu=\"$v8_target_cpu\"",
|
||||
"v8_use_snapshot=$v8_use_snapshot",
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Source Sets (aka static libraries)
|
||||
#
|
||||
@ -779,6 +780,14 @@ v8_source_set("v8_base") {
|
||||
"src/api.h",
|
||||
"src/arguments.cc",
|
||||
"src/arguments.h",
|
||||
"src/asmjs/asm-js.cc",
|
||||
"src/asmjs/asm-js.h",
|
||||
"src/asmjs/asm-types.cc",
|
||||
"src/asmjs/asm-types.h",
|
||||
"src/asmjs/asm-wasm-builder.cc",
|
||||
"src/asmjs/asm-wasm-builder.h",
|
||||
"src/asmjs/typing-asm.cc",
|
||||
"src/asmjs/typing-asm.h",
|
||||
"src/assembler.cc",
|
||||
"src/assembler.h",
|
||||
"src/assert-scope.cc",
|
||||
@ -1493,8 +1502,6 @@ v8_source_set("v8_base") {
|
||||
"src/type-info.h",
|
||||
"src/types.cc",
|
||||
"src/types.h",
|
||||
"src/typing-asm.cc",
|
||||
"src/typing-asm.h",
|
||||
"src/unicode-cache-inl.h",
|
||||
"src/unicode-cache.h",
|
||||
"src/unicode-decoder.cc",
|
||||
@ -1516,10 +1523,6 @@ v8_source_set("v8_base") {
|
||||
"src/version.h",
|
||||
"src/vm-state-inl.h",
|
||||
"src/vm-state.h",
|
||||
"src/wasm/asm-types.cc",
|
||||
"src/wasm/asm-types.h",
|
||||
"src/wasm/asm-wasm-builder.cc",
|
||||
"src/wasm/asm-wasm-builder.h",
|
||||
"src/wasm/ast-decoder.cc",
|
||||
"src/wasm/ast-decoder.h",
|
||||
"src/wasm/decoder.h",
|
||||
@ -2129,7 +2132,9 @@ if (is_component_build) {
|
||||
"src/v8dll-main.cc",
|
||||
]
|
||||
|
||||
deps = [ ":v8_dump_build_config" ]
|
||||
deps = [
|
||||
":v8_dump_build_config",
|
||||
]
|
||||
|
||||
public_deps = [
|
||||
":v8_base",
|
||||
@ -2142,7 +2147,9 @@ if (is_component_build) {
|
||||
}
|
||||
} else {
|
||||
group("v8") {
|
||||
deps = [ ":v8_dump_build_config" ]
|
||||
deps = [
|
||||
":v8_dump_build_config",
|
||||
]
|
||||
|
||||
public_deps = [
|
||||
":v8_base",
|
||||
|
@ -1418,6 +1418,48 @@ void Builtins::Generate_CompileOptimizedConcurrent(MacroAssembler* masm) {
|
||||
GenerateTailCallToReturnedCode(masm, Runtime::kCompileOptimized_Concurrent);
|
||||
}
|
||||
|
||||
void Builtins::Generate_InstantiateAsmJs(MacroAssembler* masm) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- r0 : argument count (preserved for callee)
|
||||
// -- r1 : new target (preserved for callee)
|
||||
// -- r3 : target function (preserved for callee)
|
||||
// -----------------------------------
|
||||
Label failed;
|
||||
{
|
||||
FrameScope scope(masm, StackFrame::INTERNAL);
|
||||
// Push the number of arguments to the callee.
|
||||
__ SmiTag(r0);
|
||||
__ push(r0);
|
||||
// Push a copy of the target function and the new target.
|
||||
__ push(r1);
|
||||
__ push(r3);
|
||||
|
||||
// The function.
|
||||
__ push(r1);
|
||||
// Copy arguments from caller (stdlib, foreign, heap).
|
||||
for (int i = 2; i >= 0; --i) {
|
||||
__ ldr(r4, MemOperand(fp, StandardFrameConstants::kCallerSPOffset +
|
||||
i * kPointerSize));
|
||||
__ push(r4);
|
||||
}
|
||||
// Call runtime, on success unwind frame, and parent frame.
|
||||
__ CallRuntime(Runtime::kInstantiateAsmJs, 4);
|
||||
// A smi 0 is returned on failure, an object on success.
|
||||
__ JumpIfSmi(r0, &failed);
|
||||
scope.GenerateLeaveFrame();
|
||||
__ Drop(4);
|
||||
__ Ret();
|
||||
|
||||
__ bind(&failed);
|
||||
// Restore target function and new target.
|
||||
__ pop(r3);
|
||||
__ pop(r1);
|
||||
__ pop(r0);
|
||||
__ SmiUntag(r0);
|
||||
}
|
||||
// On failure, tail call back to regular js.
|
||||
GenerateTailCallToReturnedCode(masm, Runtime::kCompileLazy);
|
||||
}
|
||||
|
||||
static void GenerateMakeCodeYoungAgainCommon(MacroAssembler* masm) {
|
||||
// For now, we are relying on the fact that make_code_young doesn't do any
|
||||
|
@ -1415,6 +1415,42 @@ void Builtins::Generate_CompileOptimizedConcurrent(MacroAssembler* masm) {
|
||||
GenerateTailCallToReturnedCode(masm, Runtime::kCompileOptimized_Concurrent);
|
||||
}
|
||||
|
||||
void Builtins::Generate_InstantiateAsmJs(MacroAssembler* masm) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- x0 : argument count (preserved for callee)
|
||||
// -- x1 : new target (preserved for callee)
|
||||
// -- x3 : target function (preserved for callee)
|
||||
// -----------------------------------
|
||||
Label failed;
|
||||
{
|
||||
FrameScope scope(masm, StackFrame::INTERNAL);
|
||||
// Push a copy of the target function and the new target.
|
||||
__ SmiTag(x0);
|
||||
// Push another copy as a parameter to the runtime call.
|
||||
__ Push(x0, x1, x3, x1);
|
||||
|
||||
// Copy arguments from caller (stdlib, foreign, heap).
|
||||
for (int i = 2; i >= 0; --i) {
|
||||
__ ldr(x4, MemOperand(fp, StandardFrameConstants::kCallerSPOffset +
|
||||
i * kPointerSize));
|
||||
__ push(x4);
|
||||
}
|
||||
// Call runtime, on success unwind frame, and parent frame.
|
||||
__ CallRuntime(Runtime::kInstantiateAsmJs, 4);
|
||||
// A smi 0 is returned on failure, an object on success.
|
||||
__ JumpIfSmi(x0, &failed);
|
||||
scope.GenerateLeaveFrame();
|
||||
__ Drop(4);
|
||||
__ Ret();
|
||||
|
||||
__ bind(&failed);
|
||||
// Restore target function and new target.
|
||||
__ Pop(x3, x1, x0);
|
||||
__ SmiUntag(x0);
|
||||
}
|
||||
// On failure, tail call back to regular js.
|
||||
GenerateTailCallToReturnedCode(masm, Runtime::kCompileLazy);
|
||||
}
|
||||
|
||||
static void GenerateMakeCodeYoungAgainCommon(MacroAssembler* masm) {
|
||||
// For now, we are relying on the fact that make_code_young doesn't do any
|
||||
|
8
src/asmjs/OWNERS
Normal file
8
src/asmjs/OWNERS
Normal file
@ -0,0 +1,8 @@
|
||||
set noparent
|
||||
|
||||
ahaas@chromium.org
|
||||
bradnelson@chromium.org
|
||||
jpp@chromium.org
|
||||
mtrofin@chromium.org
|
||||
rossberg@chromium.org
|
||||
titzer@chromium.org
|
158
src/asmjs/asm-js.cc
Normal file
158
src/asmjs/asm-js.cc
Normal file
@ -0,0 +1,158 @@
|
||||
// Copyright 2015 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/asmjs/asm-js.h"
|
||||
|
||||
#include "src/api-natives.h"
|
||||
#include "src/api.h"
|
||||
#include "src/asmjs/asm-wasm-builder.h"
|
||||
#include "src/asmjs/typing-asm.h"
|
||||
#include "src/assert-scope.h"
|
||||
#include "src/ast/ast.h"
|
||||
#include "src/ast/scopes.h"
|
||||
#include "src/execution.h"
|
||||
#include "src/factory.h"
|
||||
#include "src/handles.h"
|
||||
#include "src/isolate.h"
|
||||
#include "src/objects.h"
|
||||
#include "src/parsing/parser.h"
|
||||
|
||||
#include "src/wasm/encoder.h"
|
||||
#include "src/wasm/module-decoder.h"
|
||||
#include "src/wasm/wasm-js.h"
|
||||
#include "src/wasm/wasm-module.h"
|
||||
#include "src/wasm/wasm-result.h"
|
||||
|
||||
typedef uint8_t byte;
|
||||
|
||||
using v8::internal::wasm::ErrorThrower;
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
namespace {
|
||||
i::MaybeHandle<i::FixedArray> CompileModule(
|
||||
i::Isolate* isolate, const byte* start, const byte* end,
|
||||
ErrorThrower* thrower,
|
||||
internal::wasm::ModuleOrigin origin = i::wasm::kWasmOrigin) {
|
||||
// Decode but avoid a redundant pass over function bodies for verification.
|
||||
// Verification will happen during compilation.
|
||||
i::Zone zone(isolate->allocator());
|
||||
internal::wasm::ModuleResult result = internal::wasm::DecodeWasmModule(
|
||||
isolate, &zone, start, end, false, origin);
|
||||
|
||||
i::MaybeHandle<i::FixedArray> compiled_module;
|
||||
if (result.failed() && origin == internal::wasm::kAsmJsOrigin) {
|
||||
thrower->Error("Asm.js converted module failed to decode");
|
||||
} else if (result.failed()) {
|
||||
thrower->Failed("", result);
|
||||
} else {
|
||||
compiled_module = result.val->CompileFunctions(isolate);
|
||||
}
|
||||
|
||||
if (result.val) delete result.val;
|
||||
return compiled_module;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
MaybeHandle<FixedArray> AsmJs::ConvertAsmToWasm(ParseInfo* info) {
|
||||
ErrorThrower thrower(info->isolate(), "Asm.js -> WebAssembly conversion");
|
||||
AsmTyper typer(info->isolate(), info->zone(), *(info->script()),
|
||||
info->literal());
|
||||
typer.set_fixed_signature(true);
|
||||
if (i::FLAG_enable_simd_asmjs) {
|
||||
typer.set_allow_simd(true);
|
||||
}
|
||||
if (!typer.Validate()) {
|
||||
DCHECK(!info->isolate()->has_pending_exception());
|
||||
PrintF("Validation of asm.js module failed: %s", typer.error_message());
|
||||
return MaybeHandle<FixedArray>();
|
||||
}
|
||||
v8::internal::wasm::AsmWasmBuilder builder(info->isolate(), info->zone(),
|
||||
info->literal(), &typer);
|
||||
i::Handle<i::FixedArray> foreign_globals;
|
||||
auto module = builder.Run(&foreign_globals);
|
||||
size_t byte_length = module->end() - module->begin();
|
||||
Handle<JSArrayBuffer> buffer = info->isolate()->factory()->NewJSArrayBuffer();
|
||||
JSArrayBuffer::SetupAllocatingData(buffer, info->isolate(), byte_length,
|
||||
false, SharedFlag::kNotShared);
|
||||
uint8_t* module_bytes = reinterpret_cast<uint8_t*>(buffer->backing_store());
|
||||
memcpy(module_bytes, module->begin(), byte_length);
|
||||
Handle<FixedArray> result = info->isolate()->factory()->NewFixedArray(2);
|
||||
result->set(0, *buffer);
|
||||
result->set(1, *foreign_globals);
|
||||
return result;
|
||||
}
|
||||
|
||||
MaybeHandle<Object> AsmJs::InstantiateAsmWasm(i::Isolate* isolate,
|
||||
Handle<FixedArray> wasm_data,
|
||||
Handle<JSArrayBuffer> memory,
|
||||
Handle<JSObject> foreign) {
|
||||
i::Handle<i::JSArrayBuffer> module_bytes(
|
||||
i::JSArrayBuffer::cast(wasm_data->get(0)));
|
||||
i::Handle<i::FixedArray> foreign_globals(
|
||||
i::FixedArray::cast(wasm_data->get(1)));
|
||||
|
||||
ErrorThrower thrower(isolate, "Asm.js -> WebAssembly instantiation");
|
||||
|
||||
const byte* module_start =
|
||||
reinterpret_cast<const byte*>(module_bytes->backing_store());
|
||||
size_t module_length =
|
||||
static_cast<size_t>(module_bytes->byte_length()->Number());
|
||||
const byte* module_end = module_start + module_length;
|
||||
i::MaybeHandle<i::FixedArray> compiled =
|
||||
CompileModule(isolate, module_start, module_end, &thrower,
|
||||
internal::wasm::kAsmJsOrigin);
|
||||
if (compiled.is_null()) {
|
||||
return MaybeHandle<Object>();
|
||||
}
|
||||
i::MaybeHandle<i::JSObject> maybe_module_object =
|
||||
i::wasm::WasmModule::Instantiate(isolate, compiled.ToHandleChecked(),
|
||||
foreign, memory);
|
||||
if (maybe_module_object.is_null()) {
|
||||
return MaybeHandle<Object>();
|
||||
}
|
||||
|
||||
i::Handle<i::Name> name(isolate->factory()->InternalizeOneByteString(
|
||||
STATIC_CHAR_VECTOR("__foreign_init__")));
|
||||
|
||||
i::Handle<i::Object> module_object = maybe_module_object.ToHandleChecked();
|
||||
i::MaybeHandle<i::Object> maybe_init =
|
||||
i::Object::GetProperty(module_object, name);
|
||||
DCHECK(!maybe_init.is_null());
|
||||
|
||||
i::Handle<i::Object> init = maybe_init.ToHandleChecked();
|
||||
i::Handle<i::Object> undefined(isolate->heap()->undefined_value(), isolate);
|
||||
i::Handle<i::Object>* foreign_args_array =
|
||||
new i::Handle<i::Object>[foreign_globals->length()];
|
||||
for (int j = 0; j < foreign_globals->length(); j++) {
|
||||
if (!foreign.is_null()) {
|
||||
i::MaybeHandle<i::Name> name = i::Object::ToName(
|
||||
isolate, i::Handle<i::Object>(foreign_globals->get(j), isolate));
|
||||
if (!name.is_null()) {
|
||||
i::MaybeHandle<i::Object> val =
|
||||
i::Object::GetProperty(foreign, name.ToHandleChecked());
|
||||
if (!val.is_null()) {
|
||||
foreign_args_array[j] = val.ToHandleChecked();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
foreign_args_array[j] = undefined;
|
||||
}
|
||||
i::MaybeHandle<i::Object> retval = i::Execution::Call(
|
||||
isolate, init, undefined, foreign_globals->length(), foreign_args_array);
|
||||
delete[] foreign_args_array;
|
||||
|
||||
if (retval.is_null()) {
|
||||
thrower.Error(
|
||||
"WASM.instantiateModuleFromAsm(): foreign init function failed");
|
||||
return MaybeHandle<Object>();
|
||||
}
|
||||
return maybe_module_object;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
31
src/asmjs/asm-js.h
Normal file
31
src/asmjs/asm-js.h
Normal file
@ -0,0 +1,31 @@
|
||||
// Copyright 2016 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.
|
||||
|
||||
#ifndef V8_ASMJS_ASM_JS_H_
|
||||
#define V8_ASMJS_ASM_JS_H_
|
||||
|
||||
#ifndef V8_SHARED
|
||||
#include "src/allocation.h"
|
||||
#include "src/base/hashmap.h"
|
||||
#else
|
||||
#include "include/v8.h"
|
||||
#include "src/base/compiler-specific.h"
|
||||
#endif // !V8_SHARED
|
||||
#include "src/parsing/parser.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
// Interface to compile and instantiate for asmjs.
|
||||
class AsmJs {
|
||||
public:
|
||||
static MaybeHandle<FixedArray> ConvertAsmToWasm(i::ParseInfo* info);
|
||||
static MaybeHandle<Object> InstantiateAsmWasm(i::Isolate* isolate,
|
||||
Handle<FixedArray> wasm_data,
|
||||
Handle<JSArrayBuffer> memory,
|
||||
Handle<JSObject> foreign);
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
#endif
|
@ -4,7 +4,7 @@
|
||||
|
||||
#include "src/v8.h"
|
||||
|
||||
#include "src/wasm/asm-types.h"
|
||||
#include "src/asmjs/asm-types.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
@ -2,8 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SRC_WASM_ASM_TYPES_H_
|
||||
#define SRC_WASM_ASM_TYPES_H_
|
||||
#ifndef SRC_ASMJS_ASM_TYPES_H_
|
||||
#define SRC_ASMJS_ASM_TYPES_H_
|
||||
|
||||
#include <string>
|
||||
|
@ -10,7 +10,7 @@
|
||||
#endif
|
||||
#include <math.h>
|
||||
|
||||
#include "src/wasm/asm-wasm-builder.h"
|
||||
#include "src/asmjs/asm-wasm-builder.h"
|
||||
#include "src/wasm/switch-logic.h"
|
||||
#include "src/wasm/wasm-macro-gen.h"
|
||||
#include "src/wasm/wasm-opcodes.h"
|
@ -2,12 +2,12 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef V8_WASM_ASM_WASM_BUILDER_H_
|
||||
#define V8_WASM_ASM_WASM_BUILDER_H_
|
||||
#ifndef V8_ASMJS_ASM_WASM_BUILDER_H_
|
||||
#define V8_ASMJS_ASM_WASM_BUILDER_H_
|
||||
|
||||
#include "src/allocation.h"
|
||||
#include "src/asmjs/typing-asm.h"
|
||||
#include "src/objects.h"
|
||||
#include "src/typing-asm.h"
|
||||
#include "src/wasm/encoder.h"
|
||||
#include "src/zone.h"
|
||||
|
@ -2,7 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "src/typing-asm.h"
|
||||
#include "src/asmjs/typing-asm.h"
|
||||
|
||||
#include <limits>
|
||||
|
||||
@ -43,6 +43,7 @@ AsmTyper::AsmTyper(Isolate* isolate, Zone* zone, Script* script,
|
||||
root_(root),
|
||||
valid_(true),
|
||||
allow_simd_(false),
|
||||
fixed_signature_(false),
|
||||
property_info_(nullptr),
|
||||
intish_(0),
|
||||
stdlib_types_(zone),
|
||||
@ -67,13 +68,11 @@ AsmTyper::AsmTyper(Isolate* isolate, Zone* zone, Script* script,
|
||||
InitializeStdlib();
|
||||
}
|
||||
|
||||
|
||||
bool AsmTyper::Validate() {
|
||||
VisitAsmModule(root_);
|
||||
return valid_ && !HasStackOverflow();
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::VisitAsmModule(FunctionLiteral* fun) {
|
||||
Scope* scope = fun->scope();
|
||||
if (!scope->is_function_scope()) FAIL(fun, "not at function scope");
|
||||
@ -85,6 +84,13 @@ void AsmTyper::VisitAsmModule(FunctionLiteral* fun) {
|
||||
if (!use_asm_literal->raw_value()->AsString()->IsOneByteEqualTo("use asm"))
|
||||
FAIL(fun, "missing \"use asm\"");
|
||||
|
||||
// TODO(bradnelson): Generalize this.
|
||||
if (fixed_signature_ && scope->num_parameters() != 3) {
|
||||
FAIL(fun,
|
||||
"only asm modules with (stdlib, foreign, heap) "
|
||||
"parameters currently supported");
|
||||
}
|
||||
|
||||
// Module parameters.
|
||||
for (int i = 0; i < scope->num_parameters(); ++i) {
|
||||
Variable* param = scope->parameter(i);
|
||||
@ -143,7 +149,6 @@ void AsmTyper::VisitAsmModule(FunctionLiteral* fun) {
|
||||
"expected object export"));
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::VisitVariableDeclaration(VariableDeclaration* decl) {
|
||||
Variable* var = decl->proxy()->var();
|
||||
if (var->location() != VariableLocation::PARAMETER) {
|
||||
@ -157,7 +162,6 @@ void AsmTyper::VisitVariableDeclaration(VariableDeclaration* decl) {
|
||||
intish_ = 0;
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::VisitFunctionDeclaration(FunctionDeclaration* decl) {
|
||||
if (in_function_) {
|
||||
FAIL(decl, "function declared inside another");
|
||||
@ -172,7 +176,6 @@ void AsmTyper::VisitFunctionDeclaration(FunctionDeclaration* decl) {
|
||||
SetType(var, Type::Function());
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::VisitFunctionAnnotation(FunctionLiteral* fun) {
|
||||
// Extract result type.
|
||||
ZoneList<Statement*>* body = fun->body();
|
||||
@ -223,7 +226,6 @@ void AsmTyper::VisitFunctionAnnotation(FunctionLiteral* fun) {
|
||||
SetResult(fun, type);
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::VisitExpressionAnnotation(Expression* expr, Variable* var,
|
||||
bool is_return) {
|
||||
// Normal +x or x|0 annotations.
|
||||
@ -303,7 +305,6 @@ void AsmTyper::VisitExpressionAnnotation(Expression* expr, Variable* var,
|
||||
FAIL(expr, "invalid type annotation");
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::VisitStatements(ZoneList<Statement*>* stmts) {
|
||||
for (int i = 0; i < stmts->length(); ++i) {
|
||||
Statement* stmt = stmts->at(i);
|
||||
@ -311,30 +312,24 @@ void AsmTyper::VisitStatements(ZoneList<Statement*>* stmts) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::VisitBlock(Block* stmt) {
|
||||
RECURSE(VisitStatements(stmt->statements()));
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::VisitExpressionStatement(ExpressionStatement* stmt) {
|
||||
RECURSE(VisitWithExpectation(stmt->expression(), Type::Any(),
|
||||
"expression statement expected to be any"));
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::VisitEmptyStatement(EmptyStatement* stmt) {}
|
||||
|
||||
|
||||
void AsmTyper::VisitSloppyBlockFunctionStatement(
|
||||
SloppyBlockFunctionStatement* stmt) {
|
||||
Visit(stmt->statement());
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::VisitEmptyParentheses(EmptyParentheses* expr) { UNREACHABLE(); }
|
||||
|
||||
|
||||
void AsmTyper::VisitIfStatement(IfStatement* stmt) {
|
||||
if (!in_function_) {
|
||||
FAIL(stmt, "if statement inside module body");
|
||||
@ -348,21 +343,18 @@ void AsmTyper::VisitIfStatement(IfStatement* stmt) {
|
||||
RECURSE(Visit(stmt->else_statement()));
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::VisitContinueStatement(ContinueStatement* stmt) {
|
||||
if (!in_function_) {
|
||||
FAIL(stmt, "continue statement inside module body");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::VisitBreakStatement(BreakStatement* stmt) {
|
||||
if (!in_function_) {
|
||||
FAIL(stmt, "continue statement inside module body");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::VisitReturnStatement(ReturnStatement* stmt) {
|
||||
// Handle module return statement in VisitAsmModule.
|
||||
if (!in_function_) {
|
||||
@ -381,12 +373,10 @@ void AsmTyper::VisitReturnStatement(ReturnStatement* stmt) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::VisitWithStatement(WithStatement* stmt) {
|
||||
FAIL(stmt, "bad with statement");
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::VisitSwitchStatement(SwitchStatement* stmt) {
|
||||
if (!in_function_) {
|
||||
FAIL(stmt, "switch statement inside module body");
|
||||
@ -427,10 +417,8 @@ void AsmTyper::VisitSwitchStatement(SwitchStatement* stmt) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::VisitCaseClause(CaseClause* clause) { UNREACHABLE(); }
|
||||
|
||||
|
||||
void AsmTyper::VisitDoWhileStatement(DoWhileStatement* stmt) {
|
||||
if (!in_function_) {
|
||||
FAIL(stmt, "do statement inside module body");
|
||||
@ -443,7 +431,6 @@ void AsmTyper::VisitDoWhileStatement(DoWhileStatement* stmt) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::VisitWhileStatement(WhileStatement* stmt) {
|
||||
if (!in_function_) {
|
||||
FAIL(stmt, "while statement inside module body");
|
||||
@ -456,7 +443,6 @@ void AsmTyper::VisitWhileStatement(WhileStatement* stmt) {
|
||||
RECURSE(Visit(stmt->body()));
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::VisitForStatement(ForStatement* stmt) {
|
||||
if (!in_function_) {
|
||||
FAIL(stmt, "for statement inside module body");
|
||||
@ -477,32 +463,26 @@ void AsmTyper::VisitForStatement(ForStatement* stmt) {
|
||||
RECURSE(Visit(stmt->body()));
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::VisitForInStatement(ForInStatement* stmt) {
|
||||
FAIL(stmt, "for-in statement encountered");
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::VisitForOfStatement(ForOfStatement* stmt) {
|
||||
FAIL(stmt, "for-of statement encountered");
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::VisitTryCatchStatement(TryCatchStatement* stmt) {
|
||||
FAIL(stmt, "try statement encountered");
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
|
||||
FAIL(stmt, "try statement encountered");
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::VisitDebuggerStatement(DebuggerStatement* stmt) {
|
||||
FAIL(stmt, "debugger statement encountered");
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::VisitFunctionLiteral(FunctionLiteral* expr) {
|
||||
if (in_function_) {
|
||||
FAIL(expr, "invalid nested function");
|
||||
@ -526,17 +506,14 @@ void AsmTyper::VisitFunctionLiteral(FunctionLiteral* expr) {
|
||||
RECURSE(IntersectResult(expr, type));
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) {
|
||||
FAIL(expr, "function info literal encountered");
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::VisitDoExpression(DoExpression* expr) {
|
||||
FAIL(expr, "do-expression encountered");
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::VisitConditional(Conditional* expr) {
|
||||
if (!in_function_) {
|
||||
FAIL(expr, "ternary operator inside module body");
|
||||
@ -572,7 +549,6 @@ void AsmTyper::VisitConditional(Conditional* expr) {
|
||||
RECURSE(IntersectResult(expr, then_type));
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::VisitVariableProxy(VariableProxy* expr) {
|
||||
Variable* var = expr->var();
|
||||
VariableInfo* info = GetVariableInfo(var);
|
||||
@ -627,15 +603,12 @@ void AsmTyper::VisitLiteral(Literal* expr, bool is_return) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::VisitLiteral(Literal* expr) { VisitLiteral(expr, false); }
|
||||
|
||||
|
||||
void AsmTyper::VisitRegExpLiteral(RegExpLiteral* expr) {
|
||||
FAIL(expr, "regular expression encountered");
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::VisitObjectLiteral(ObjectLiteral* expr) {
|
||||
if (in_function_) {
|
||||
FAIL(expr, "object literal in function");
|
||||
@ -653,7 +626,6 @@ void AsmTyper::VisitObjectLiteral(ObjectLiteral* expr) {
|
||||
RECURSE(IntersectResult(expr, Type::Object()));
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::VisitArrayLiteral(ArrayLiteral* expr) {
|
||||
if (in_function_) {
|
||||
FAIL(expr, "array literal inside a function");
|
||||
@ -673,7 +645,6 @@ void AsmTyper::VisitArrayLiteral(ArrayLiteral* expr) {
|
||||
RECURSE(IntersectResult(expr, Type::Array(elem_type, zone())));
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::VisitAssignment(Assignment* expr) {
|
||||
// Handle function tables and everything else in different passes.
|
||||
if (!in_function_) {
|
||||
@ -739,17 +710,14 @@ void AsmTyper::VisitAssignment(Assignment* expr) {
|
||||
RECURSE(IntersectResult(expr, target_type));
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::VisitYield(Yield* expr) {
|
||||
FAIL(expr, "yield expression encountered");
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::VisitThrow(Throw* expr) {
|
||||
FAIL(expr, "throw statement encountered");
|
||||
}
|
||||
|
||||
|
||||
int AsmTyper::ElementShiftSize(Type* type) {
|
||||
if (type->Is(cache_.kAsmSize8)) return 0;
|
||||
if (type->Is(cache_.kAsmSize16)) return 1;
|
||||
@ -758,7 +726,6 @@ int AsmTyper::ElementShiftSize(Type* type) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
Type* AsmTyper::StorageType(Type* type) {
|
||||
if (type->Is(cache_.kAsmInt)) {
|
||||
return cache_.kAsmInt;
|
||||
@ -767,7 +734,6 @@ Type* AsmTyper::StorageType(Type* type) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::VisitHeapAccess(Property* expr, bool assigning,
|
||||
Type* assignment_type) {
|
||||
ArrayType* array_type = computed_type_->AsArray();
|
||||
@ -861,7 +827,6 @@ void AsmTyper::VisitHeapAccess(Property* expr, bool assigning,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool AsmTyper::IsStdlibObject(Expression* expr) {
|
||||
VariableProxy* proxy = expr->AsVariableProxy();
|
||||
if (proxy == nullptr) {
|
||||
@ -881,7 +846,6 @@ bool AsmTyper::IsStdlibObject(Expression* expr) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Expression* AsmTyper::GetReceiverOfPropertyAccess(Expression* expr,
|
||||
const char* name) {
|
||||
Property* property = expr->AsProperty();
|
||||
@ -896,25 +860,21 @@ Expression* AsmTyper::GetReceiverOfPropertyAccess(Expression* expr,
|
||||
return property->obj();
|
||||
}
|
||||
|
||||
|
||||
bool AsmTyper::IsMathObject(Expression* expr) {
|
||||
Expression* obj = GetReceiverOfPropertyAccess(expr, "Math");
|
||||
return obj && IsStdlibObject(obj);
|
||||
}
|
||||
|
||||
|
||||
bool AsmTyper::IsSIMDObject(Expression* expr) {
|
||||
Expression* obj = GetReceiverOfPropertyAccess(expr, "SIMD");
|
||||
return obj && IsStdlibObject(obj);
|
||||
}
|
||||
|
||||
|
||||
bool AsmTyper::IsSIMDTypeObject(Expression* expr, const char* name) {
|
||||
Expression* obj = GetReceiverOfPropertyAccess(expr, name);
|
||||
return obj && IsSIMDObject(obj);
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::VisitProperty(Property* expr) {
|
||||
if (IsMathObject(expr->obj())) {
|
||||
VisitLibraryAccess(&stdlib_math_types_, expr);
|
||||
@ -1078,7 +1038,6 @@ void AsmTyper::VisitCall(Call* expr) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::VisitCallNew(CallNew* expr) {
|
||||
if (in_function_) {
|
||||
FAIL(expr, "new not allowed in module function");
|
||||
@ -1103,12 +1062,10 @@ void AsmTyper::VisitCallNew(CallNew* expr) {
|
||||
FAIL(expr, "ill-typed new operator");
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::VisitCallRuntime(CallRuntime* expr) {
|
||||
FAIL(expr, "runtime call not allowed");
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::VisitUnaryOperation(UnaryOperation* expr) {
|
||||
if (!in_function_) {
|
||||
FAIL(expr, "unary operator inside module body");
|
||||
@ -1130,12 +1087,10 @@ void AsmTyper::VisitUnaryOperation(UnaryOperation* expr) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::VisitCountOperation(CountOperation* expr) {
|
||||
FAIL(expr, "increment or decrement operator encountered");
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::VisitIntegerBitwiseOperator(BinaryOperation* expr,
|
||||
Type* left_expected,
|
||||
Type* right_expected,
|
||||
@ -1179,7 +1134,6 @@ void AsmTyper::VisitIntegerBitwiseOperator(BinaryOperation* expr,
|
||||
RECURSE(IntersectResult(expr, result_type));
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::VisitBinaryOperation(BinaryOperation* expr) {
|
||||
if (!in_function_) {
|
||||
if (expr->op() != Token::BIT_OR && expr->op() != Token::MUL) {
|
||||
@ -1377,7 +1331,6 @@ void AsmTyper::VisitBinaryOperation(BinaryOperation* expr) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::VisitCompareOperation(CompareOperation* expr) {
|
||||
if (!in_function_) {
|
||||
FAIL(expr, "comparison inside module body");
|
||||
@ -1416,12 +1369,10 @@ void AsmTyper::VisitCompareOperation(CompareOperation* expr) {
|
||||
RECURSE(IntersectResult(expr, cache_.kAsmSigned));
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::VisitThisFunction(ThisFunction* expr) {
|
||||
FAIL(expr, "this function not allowed");
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::VisitDeclarations(ZoneList<Declaration*>* decls) {
|
||||
for (int i = 0; i < decls->length(); ++i) {
|
||||
Declaration* decl = decls->at(i);
|
||||
@ -1429,30 +1380,24 @@ void AsmTyper::VisitDeclarations(ZoneList<Declaration*>* decls) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::VisitImportDeclaration(ImportDeclaration* decl) {
|
||||
FAIL(decl, "import declaration encountered");
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::VisitClassLiteral(ClassLiteral* expr) {
|
||||
FAIL(expr, "class literal not allowed");
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::VisitSpread(Spread* expr) { FAIL(expr, "spread not allowed"); }
|
||||
|
||||
|
||||
void AsmTyper::VisitSuperPropertyReference(SuperPropertyReference* expr) {
|
||||
FAIL(expr, "super property reference not allowed");
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::VisitSuperCallReference(SuperCallReference* expr) {
|
||||
FAIL(expr, "call reference not allowed");
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::InitializeStdlibSIMD() {
|
||||
#define V(NAME, Name, name, lane_count, lane_type) \
|
||||
{ \
|
||||
@ -1468,7 +1413,6 @@ void AsmTyper::InitializeStdlibSIMD() {
|
||||
#undef V
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::InitializeStdlib() {
|
||||
if (allow_simd_) {
|
||||
InitializeStdlibSIMD();
|
||||
@ -1544,7 +1488,6 @@ void AsmTyper::InitializeStdlib() {
|
||||
#undef TYPED_ARRAY
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::VisitLibraryAccess(ObjectTypeMap* map, Property* expr) {
|
||||
Literal* key = expr->key()->AsLiteral();
|
||||
if (key == nullptr || !key->IsPropertyName())
|
||||
@ -1557,7 +1500,6 @@ void AsmTyper::VisitLibraryAccess(ObjectTypeMap* map, Property* expr) {
|
||||
property_info_ = info;
|
||||
}
|
||||
|
||||
|
||||
AsmTyper::VariableInfo* AsmTyper::LibType(ObjectTypeMap* map,
|
||||
Handle<String> name) {
|
||||
base::SmartArrayPointer<char> aname = name->ToCString();
|
||||
@ -1568,13 +1510,11 @@ AsmTyper::VariableInfo* AsmTyper::LibType(ObjectTypeMap* map,
|
||||
return i->second;
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::SetType(Variable* variable, Type* type) {
|
||||
VariableInfo* info = MakeVariableInfo(variable);
|
||||
info->type = type;
|
||||
}
|
||||
|
||||
|
||||
Type* AsmTyper::GetType(Variable* variable) {
|
||||
VariableInfo* info = GetVariableInfo(variable);
|
||||
if (!info) return nullptr;
|
||||
@ -1610,7 +1550,6 @@ void AsmTyper::SetVariableInfo(Variable* variable, const VariableInfo* info) {
|
||||
dest->standard_member = info->standard_member;
|
||||
}
|
||||
|
||||
|
||||
AsmTyper::StandardMember AsmTyper::VariableAsStandardMember(
|
||||
Variable* variable) {
|
||||
VariableInfo* info = GetVariableInfo(variable);
|
||||
@ -1618,13 +1557,11 @@ AsmTyper::StandardMember AsmTyper::VariableAsStandardMember(
|
||||
return info->standard_member;
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::SetResult(Expression* expr, Type* type) {
|
||||
computed_type_ = type;
|
||||
bounds_.set(expr, Bounds(computed_type_));
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::IntersectResult(Expression* expr, Type* type) {
|
||||
computed_type_ = type;
|
||||
Type* bounded_type = Type::Intersect(computed_type_, expected_type_, zone());
|
||||
@ -1640,7 +1577,6 @@ void AsmTyper::IntersectResult(Expression* expr, Type* type) {
|
||||
bounds_.set(expr, Bounds(bounded_type));
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::VisitWithExpectation(Expression* expr, Type* expected_type,
|
||||
const char* msg) {
|
||||
Type* save = expected_type_;
|
||||
@ -1659,11 +1595,9 @@ void AsmTyper::VisitWithExpectation(Expression* expr, Type* expected_type,
|
||||
expected_type_ = save;
|
||||
}
|
||||
|
||||
|
||||
void AsmTyper::VisitRewritableExpression(RewritableExpression* expr) {
|
||||
RECURSE(Visit(expr->expression()));
|
||||
}
|
||||
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
@ -2,8 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef V8_TYPING_ASM_H_
|
||||
#define V8_TYPING_ASM_H_
|
||||
#ifndef V8_ASMJS_TYPING_ASM_H_
|
||||
#define V8_ASMJS_TYPING_ASM_H_
|
||||
|
||||
#include "src/allocation.h"
|
||||
#include "src/ast/ast-type-bounds.h"
|
||||
@ -24,6 +24,7 @@ class AsmTyper : public AstVisitor {
|
||||
FunctionLiteral* root);
|
||||
bool Validate();
|
||||
void set_allow_simd(bool simd) { allow_simd_ = simd; }
|
||||
void set_fixed_signature(bool fixed) { fixed_signature_ = fixed; }
|
||||
const char* error_message() { return error_message_; }
|
||||
const AstTypeBounds* bounds() { return &bounds_; }
|
||||
|
||||
@ -71,6 +72,7 @@ class AsmTyper : public AstVisitor {
|
||||
FunctionLiteral* root_;
|
||||
bool valid_;
|
||||
bool allow_simd_;
|
||||
bool fixed_signature_;
|
||||
|
||||
struct VariableInfo : public ZoneObject {
|
||||
Type* type;
|
@ -3450,9 +3450,7 @@ bool Genesis::InstallSpecialObjects(Handle<Context> native_context) {
|
||||
JSObject::AddProperty(global, debug_string, global_proxy, DONT_ENUM);
|
||||
}
|
||||
|
||||
if (FLAG_expose_wasm) {
|
||||
WasmJs::Install(isolate, global);
|
||||
}
|
||||
WasmJs::Install(isolate, global);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -225,6 +225,7 @@ class CodeStubAssembler;
|
||||
V(JSEntryTrampoline, BUILTIN, kNoExtraICState) \
|
||||
V(JSConstructEntryTrampoline, BUILTIN, kNoExtraICState) \
|
||||
V(ResumeGeneratorTrampoline, BUILTIN, kNoExtraICState) \
|
||||
V(InstantiateAsmJs, BUILTIN, kNoExtraICState) \
|
||||
V(CompileLazy, BUILTIN, kNoExtraICState) \
|
||||
V(CompileBaseline, BUILTIN, kNoExtraICState) \
|
||||
V(CompileOptimized, BUILTIN, kNoExtraICState) \
|
||||
@ -480,6 +481,7 @@ class Builtins {
|
||||
static void Generate_AllocateInNewSpace(MacroAssembler* masm);
|
||||
static void Generate_AllocateInOldSpace(MacroAssembler* masm);
|
||||
static void Generate_ConstructedNonConstructable(MacroAssembler* masm);
|
||||
static void Generate_InstantiateAsmJs(MacroAssembler* masm);
|
||||
static void Generate_CompileLazy(MacroAssembler* masm);
|
||||
static void Generate_CompileBaseline(MacroAssembler* masm);
|
||||
static void Generate_InOptimizationQueue(MacroAssembler* masm);
|
||||
|
@ -6,6 +6,8 @@
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "src/asmjs/asm-js.h"
|
||||
#include "src/asmjs/typing-asm.h"
|
||||
#include "src/ast/ast-numbering.h"
|
||||
#include "src/ast/prettyprinter.h"
|
||||
#include "src/ast/scopeinfo.h"
|
||||
@ -30,7 +32,6 @@
|
||||
#include "src/parsing/scanner-character-streams.h"
|
||||
#include "src/runtime-profiler.h"
|
||||
#include "src/snapshot/code-serializer.h"
|
||||
#include "src/typing-asm.h"
|
||||
#include "src/vm-state-inl.h"
|
||||
|
||||
namespace v8 {
|
||||
@ -477,14 +478,12 @@ bool GenerateUnoptimizedCode(CompilationInfo* info) {
|
||||
bool success;
|
||||
EnsureFeedbackMetadata(info);
|
||||
if (FLAG_validate_asm && info->scope()->asm_module()) {
|
||||
AsmTyper typer(info->isolate(), info->zone(), *(info->script()),
|
||||
info->literal());
|
||||
if (FLAG_enable_simd_asmjs) {
|
||||
typer.set_allow_simd(true);
|
||||
}
|
||||
if (!typer.Validate()) {
|
||||
DCHECK(!info->isolate()->has_pending_exception());
|
||||
PrintF("Validation of asm.js module failed: %s", typer.error_message());
|
||||
MaybeHandle<FixedArray> wasm_data;
|
||||
wasm_data = AsmJs::ConvertAsmToWasm(info->parse_info());
|
||||
if (!wasm_data.is_null()) {
|
||||
info->shared_info()->set_asm_wasm_data(*wasm_data.ToHandleChecked());
|
||||
info->SetCode(info->isolate()->builtins()->InstantiateAsmJs());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (FLAG_ignition && UseIgnition(info)) {
|
||||
|
@ -1019,6 +1019,46 @@ void Builtins::Generate_CompileOptimizedConcurrent(MacroAssembler* masm) {
|
||||
GenerateTailCallToReturnedCode(masm, Runtime::kCompileOptimized_Concurrent);
|
||||
}
|
||||
|
||||
void Builtins::Generate_InstantiateAsmJs(MacroAssembler* masm) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- eax : argument count (preserved for callee)
|
||||
// -- edx : new target (preserved for callee)
|
||||
// -- edi : target function (preserved for callee)
|
||||
// -----------------------------------
|
||||
Label failed;
|
||||
{
|
||||
FrameScope scope(masm, StackFrame::INTERNAL);
|
||||
// Push the number of arguments to the callee.
|
||||
__ SmiTag(eax);
|
||||
__ push(eax);
|
||||
// Push a copy of the target function and the new target.
|
||||
__ push(edi);
|
||||
__ push(edx);
|
||||
|
||||
// The function.
|
||||
__ push(edi);
|
||||
// Copy arguments from caller (stdlib, foreign, heap).
|
||||
for (int i = 2; i >= 0; --i) {
|
||||
__ push(Operand(
|
||||
ebp, StandardFrameConstants::kCallerSPOffset + i * kPointerSize));
|
||||
}
|
||||
// Call runtime, on success unwind frame, and parent frame.
|
||||
__ CallRuntime(Runtime::kInstantiateAsmJs, 4);
|
||||
// A smi 0 is returned on failure, an object on success.
|
||||
__ JumpIfSmi(eax, &failed, Label::kNear);
|
||||
scope.GenerateLeaveFrame();
|
||||
__ ret(4 * kPointerSize);
|
||||
|
||||
__ bind(&failed);
|
||||
// Restore target function and new target.
|
||||
__ pop(edx);
|
||||
__ pop(edi);
|
||||
__ pop(eax);
|
||||
__ SmiUntag(eax);
|
||||
}
|
||||
// On failure, tail call back to regular js.
|
||||
GenerateTailCallToReturnedCode(masm, Runtime::kCompileLazy);
|
||||
}
|
||||
|
||||
static void GenerateMakeCodeYoungAgainCommon(MacroAssembler* masm) {
|
||||
// For now, we are relying on the fact that make_code_young doesn't do any
|
||||
|
@ -1413,6 +1413,42 @@ void Builtins::Generate_CompileOptimizedConcurrent(MacroAssembler* masm) {
|
||||
GenerateTailCallToReturnedCode(masm, Runtime::kCompileOptimized_Concurrent);
|
||||
}
|
||||
|
||||
void Builtins::Generate_InstantiateAsmJs(MacroAssembler* masm) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- a0 : argument count (preserved for callee)
|
||||
// -- a1 : new target (preserved for callee)
|
||||
// -- a3 : target function (preserved for callee)
|
||||
// -----------------------------------
|
||||
Label failed;
|
||||
{
|
||||
FrameScope scope(masm, StackFrame::INTERNAL);
|
||||
// Push a copy of the target function and the new target.
|
||||
// Push function as parameter to the runtime call.
|
||||
__ SmiTag(a0);
|
||||
__ Push(a0, a1, a3, a1);
|
||||
|
||||
// Copy arguments from caller (stdlib, foreign, heap).
|
||||
for (int i = 2; i >= 0; --i) {
|
||||
__ lw(a3, MemOperand(fp, StandardFrameConstants::kCallerSPOffset +
|
||||
i * kPointerSize));
|
||||
__ push(a3);
|
||||
}
|
||||
// Call runtime, on success unwind frame, and parent frame.
|
||||
__ CallRuntime(Runtime::kInstantiateAsmJs, 4);
|
||||
// A smi 0 is returned on failure, an object on success.
|
||||
__ JumpIfSmi(a0, &failed);
|
||||
scope.GenerateLeaveFrame();
|
||||
__ Drop(4);
|
||||
__ Ret();
|
||||
|
||||
__ bind(&failed);
|
||||
// Restore target function and new target.
|
||||
__ Pop(a0, a1, a3);
|
||||
__ SmiUntag(a0);
|
||||
}
|
||||
// On failure, tail call back to regular js.
|
||||
GenerateTailCallToReturnedCode(masm, Runtime::kCompileLazy);
|
||||
}
|
||||
|
||||
static void GenerateMakeCodeYoungAgainCommon(MacroAssembler* masm) {
|
||||
// For now, we are relying on the fact that make_code_young doesn't do any
|
||||
|
@ -1397,6 +1397,42 @@ void Builtins::Generate_CompileOptimizedConcurrent(MacroAssembler* masm) {
|
||||
GenerateTailCallToReturnedCode(masm, Runtime::kCompileOptimized_Concurrent);
|
||||
}
|
||||
|
||||
void Builtins::Generate_InstantiateAsmJs(MacroAssembler* masm) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- a0 : argument count (preserved for callee)
|
||||
// -- a1 : new target (preserved for callee)
|
||||
// -- a3 : target function (preserved for callee)
|
||||
// -----------------------------------
|
||||
Label failed;
|
||||
{
|
||||
FrameScope scope(masm, StackFrame::INTERNAL);
|
||||
// Push a copy of the target function and the new target.
|
||||
// Push function as parameter to the runtime call.
|
||||
__ SmiTag(a0);
|
||||
__ Push(a0, a1, a3, a1);
|
||||
|
||||
// Copy arguments from caller (stdlib, foreign, heap).
|
||||
for (int i = 2; i >= 0; --i) {
|
||||
__ lw(a3, MemOperand(fp, StandardFrameConstants::kCallerSPOffset +
|
||||
i * kPointerSize));
|
||||
__ push(a3);
|
||||
}
|
||||
// Call runtime, on success unwind frame, and parent frame.
|
||||
__ CallRuntime(Runtime::kInstantiateAsmJs, 4);
|
||||
// A smi 0 is returned on failure, an object on success.
|
||||
__ JumpIfSmi(a0, &failed);
|
||||
scope.GenerateLeaveFrame();
|
||||
__ Drop(4);
|
||||
__ Ret();
|
||||
|
||||
__ bind(&failed);
|
||||
// Restore target function and new target.
|
||||
__ Pop(a0, a1, a3);
|
||||
__ SmiUntag(a0);
|
||||
}
|
||||
// On failure, tail call back to regular js.
|
||||
GenerateTailCallToReturnedCode(masm, Runtime::kCompileLazy);
|
||||
}
|
||||
|
||||
static void GenerateMakeCodeYoungAgainCommon(MacroAssembler* masm) {
|
||||
// For now, we are relying on the fact that make_code_young doesn't do any
|
||||
|
@ -564,7 +564,7 @@ void SharedFunctionInfo::SharedFunctionInfoVerify() {
|
||||
VerifyObjectField(kScopeInfoOffset);
|
||||
VerifyObjectField(kInstanceClassNameOffset);
|
||||
CHECK(function_data()->IsUndefined(GetIsolate()) || IsApiFunction() ||
|
||||
HasBytecodeArray());
|
||||
HasBytecodeArray() || HasAsmWasmData());
|
||||
VerifyObjectField(kFunctionDataOffset);
|
||||
VerifyObjectField(kScriptOffset);
|
||||
VerifyObjectField(kDebugInfoOffset);
|
||||
|
@ -6084,6 +6084,25 @@ void SharedFunctionInfo::ClearBytecodeArray() {
|
||||
set_function_data(GetHeap()->undefined_value());
|
||||
}
|
||||
|
||||
bool SharedFunctionInfo::HasAsmWasmData() {
|
||||
return function_data()->IsFixedArray();
|
||||
}
|
||||
|
||||
FixedArray* SharedFunctionInfo::asm_wasm_data() {
|
||||
DCHECK(HasAsmWasmData());
|
||||
return FixedArray::cast(function_data());
|
||||
}
|
||||
|
||||
void SharedFunctionInfo::set_asm_wasm_data(FixedArray* data) {
|
||||
DCHECK(function_data()->IsUndefined(GetIsolate()) || HasAsmWasmData());
|
||||
set_function_data(data);
|
||||
}
|
||||
|
||||
void SharedFunctionInfo::ClearAsmWasmData() {
|
||||
DCHECK(function_data()->IsUndefined(GetIsolate()) || HasAsmWasmData());
|
||||
set_function_data(GetHeap()->undefined_value());
|
||||
}
|
||||
|
||||
bool SharedFunctionInfo::HasBuiltinFunctionId() {
|
||||
return function_identifier()->IsSmi();
|
||||
}
|
||||
|
@ -6916,6 +6916,7 @@ class SharedFunctionInfo: public HeapObject {
|
||||
// Currently it has one of:
|
||||
// - a FunctionTemplateInfo to make benefit the API [IsApiFunction()].
|
||||
// - a BytecodeArray for the interpreter [HasBytecodeArray()].
|
||||
// - a FixedArray with Asm->Wasm conversion [HasAsmWasmData()].
|
||||
DECL_ACCESSORS(function_data, Object)
|
||||
|
||||
inline bool IsApiFunction();
|
||||
@ -6925,6 +6926,10 @@ class SharedFunctionInfo: public HeapObject {
|
||||
inline BytecodeArray* bytecode_array();
|
||||
inline void set_bytecode_array(BytecodeArray* bytecode);
|
||||
inline void ClearBytecodeArray();
|
||||
inline bool HasAsmWasmData();
|
||||
inline FixedArray* asm_wasm_data();
|
||||
inline void set_asm_wasm_data(FixedArray* data);
|
||||
inline void ClearAsmWasmData();
|
||||
|
||||
// [function identifier]: This field holds an additional identifier for the
|
||||
// function.
|
||||
|
@ -1415,6 +1415,42 @@ void Builtins::Generate_CompileOptimizedConcurrent(MacroAssembler* masm) {
|
||||
GenerateTailCallToReturnedCode(masm, Runtime::kCompileOptimized_Concurrent);
|
||||
}
|
||||
|
||||
void Builtins::Generate_InstantiateAsmJs(MacroAssembler* masm) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- r3 : argument count (preserved for callee)
|
||||
// -- r4 : new target (preserved for callee)
|
||||
// -- r6 : target function (preserved for callee)
|
||||
// -----------------------------------
|
||||
Label failed;
|
||||
{
|
||||
FrameScope scope(masm, StackFrame::INTERNAL);
|
||||
// Push a copy of the target function and the new target.
|
||||
// Push function as parameter to the runtime call.
|
||||
__ SmiTag(r3);
|
||||
__ Push(r3, r4, r6, r4);
|
||||
|
||||
// Copy arguments from caller (stdlib, foreign, heap).
|
||||
for (int i = 2; i >= 0; --i) {
|
||||
__ LoadP(r4, MemOperand(fp, StandardFrameConstants::kCallerSPOffset +
|
||||
i * kPointerSize));
|
||||
__ push(r4);
|
||||
}
|
||||
// Call runtime, on success unwind frame, and parent frame.
|
||||
__ CallRuntime(Runtime::kInstantiateAsmJs, 4);
|
||||
// A smi 0 is returned on failure, an object on success.
|
||||
__ JumpIfSmi(r3, &failed);
|
||||
scope.GenerateLeaveFrame();
|
||||
__ Drop(4);
|
||||
__ Ret();
|
||||
|
||||
__ bind(&failed);
|
||||
// Restore target function and new target.
|
||||
__ Pop(r3, r4, r6);
|
||||
__ SmiUntag(r3);
|
||||
}
|
||||
// On failure, tail call back to regular js.
|
||||
GenerateTailCallToReturnedCode(masm, Runtime::kCompileLazy);
|
||||
}
|
||||
|
||||
static void GenerateMakeCodeYoungAgainCommon(MacroAssembler* masm) {
|
||||
// For now, we are relying on the fact that make_code_young doesn't do any
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "src/runtime/runtime-utils.h"
|
||||
|
||||
#include "src/arguments.h"
|
||||
#include "src/asmjs/asm-js.h"
|
||||
#include "src/compiler.h"
|
||||
#include "src/deoptimizer.h"
|
||||
#include "src/frames-inl.h"
|
||||
@ -79,6 +80,31 @@ RUNTIME_FUNCTION(Runtime_CompileOptimized_NotConcurrent) {
|
||||
return function->code();
|
||||
}
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_InstantiateAsmJs) {
|
||||
HandleScope scope(isolate);
|
||||
DCHECK_EQ(args.length(), 4);
|
||||
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
|
||||
|
||||
Handle<JSObject> foreign;
|
||||
if (args[2]->IsJSObject()) {
|
||||
foreign = args.at<i::JSObject>(2);
|
||||
}
|
||||
Handle<JSArrayBuffer> memory;
|
||||
if (args[3]->IsJSArrayBuffer()) {
|
||||
memory = args.at<i::JSArrayBuffer>(3);
|
||||
}
|
||||
if (args[1]->IsJSObject()) {
|
||||
MaybeHandle<Object> result;
|
||||
result = AsmJs::InstantiateAsmWasm(
|
||||
isolate, handle(function->shared()->asm_wasm_data()), memory, foreign);
|
||||
if (!result.is_null()) {
|
||||
return *result.ToHandleChecked();
|
||||
}
|
||||
}
|
||||
// Remove wasm data and return a smi 0 to indicate failure.
|
||||
function->shared()->ClearAsmWasmData();
|
||||
return Smi::FromInt(0);
|
||||
}
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_NotifyStubFailure) {
|
||||
HandleScope scope(isolate);
|
||||
@ -89,7 +115,6 @@ RUNTIME_FUNCTION(Runtime_NotifyStubFailure) {
|
||||
return isolate->heap()->undefined_value();
|
||||
}
|
||||
|
||||
|
||||
class ActivationsFinder : public ThreadVisitor {
|
||||
public:
|
||||
Code* code_;
|
||||
|
@ -127,7 +127,8 @@ namespace internal {
|
||||
F(NotifyDeoptimized, 1, 1) \
|
||||
F(CompileForOnStackReplacement, 1, 1) \
|
||||
F(TryInstallOptimizedCode, 1, 1) \
|
||||
F(ResolvePossiblyDirectEval, 6, 1)
|
||||
F(ResolvePossiblyDirectEval, 6, 1) \
|
||||
F(InstantiateAsmJs, 4, 1)
|
||||
|
||||
#define FOR_EACH_INTRINSIC_DATE(F) \
|
||||
F(IsDate, 1, 1) \
|
||||
|
@ -1396,6 +1396,43 @@ void Builtins::Generate_CompileOptimizedConcurrent(MacroAssembler* masm) {
|
||||
GenerateTailCallToReturnedCode(masm, Runtime::kCompileOptimized_Concurrent);
|
||||
}
|
||||
|
||||
void Builtins::Generate_InstantiateAsmJs(MacroAssembler* masm) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- r2 : argument count (preserved for callee)
|
||||
// -- r3 : new target (preserved for callee)
|
||||
// -- r5 : target function (preserved for callee)
|
||||
// -----------------------------------
|
||||
Label failed;
|
||||
{
|
||||
FrameScope scope(masm, StackFrame::INTERNAL);
|
||||
// Push a copy of the target function and the new target.
|
||||
__ SmiTag(r2);
|
||||
// Push another copy as a parameter to the runtime call.
|
||||
__ Push(r2, r3, r5, r3);
|
||||
|
||||
// Copy arguments from caller (stdlib, foreign, heap).
|
||||
for (int i = 2; i >= 0; --i) {
|
||||
__ LoadP(r4, MemOperand(fp, StandardFrameConstants::kCallerSPOffset +
|
||||
i * kPointerSize));
|
||||
__ push(r4);
|
||||
}
|
||||
// Call runtime, on success unwind frame, and parent frame.
|
||||
__ CallRuntime(Runtime::kInstantiateAsmJs, 4);
|
||||
// A smi 0 is returned on failure, an object on success.
|
||||
__ JumpIfSmi(r2, &failed);
|
||||
scope.GenerateLeaveFrame();
|
||||
__ Drop(4);
|
||||
__ Ret();
|
||||
|
||||
__ bind(&failed);
|
||||
// Restore target function and new target.
|
||||
__ Pop(r2, r3, r5);
|
||||
__ SmiUntag(r2);
|
||||
}
|
||||
// On failure, tail call back to regular js.
|
||||
GenerateTailCallToReturnedCode(masm, Runtime::kCompileLazy);
|
||||
}
|
||||
|
||||
static void GenerateMakeCodeYoungAgainCommon(MacroAssembler* masm) {
|
||||
// For now, we are relying on the fact that make_code_young doesn't do any
|
||||
// garbage collection which allows us to save/restore the registers without
|
||||
|
14
src/v8.gyp
14
src/v8.gyp
@ -418,6 +418,14 @@
|
||||
'api-natives.h',
|
||||
'arguments.cc',
|
||||
'arguments.h',
|
||||
'asmjs/asm-js.cc',
|
||||
'asmjs/asm-js.h',
|
||||
'asmjs/asm-types.cc',
|
||||
'asmjs/asm-types.h',
|
||||
'asmjs/asm-wasm-builder.cc',
|
||||
'asmjs/asm-wasm-builder.h',
|
||||
'asmjs/typing-asm.cc',
|
||||
'asmjs/typing-asm.h',
|
||||
'assembler.cc',
|
||||
'assembler.h',
|
||||
'assert-scope.h',
|
||||
@ -1137,8 +1145,6 @@
|
||||
'type-info.h',
|
||||
'types.cc',
|
||||
'types.h',
|
||||
'typing-asm.cc',
|
||||
'typing-asm.h',
|
||||
'unicode-inl.h',
|
||||
'unicode.cc',
|
||||
'unicode.h',
|
||||
@ -1161,10 +1167,6 @@
|
||||
'version.h',
|
||||
'vm-state-inl.h',
|
||||
'vm-state.h',
|
||||
'wasm/asm-types.cc',
|
||||
'wasm/asm-types.h',
|
||||
'wasm/asm-wasm-builder.cc',
|
||||
'wasm/asm-wasm-builder.h',
|
||||
'wasm/ast-decoder.cc',
|
||||
'wasm/ast-decoder.h',
|
||||
'wasm/decoder.h',
|
||||
|
@ -4,6 +4,8 @@
|
||||
|
||||
#include "src/api-natives.h"
|
||||
#include "src/api.h"
|
||||
#include "src/asmjs/asm-wasm-builder.h"
|
||||
#include "src/asmjs/typing-asm.h"
|
||||
#include "src/assert-scope.h"
|
||||
#include "src/ast/ast.h"
|
||||
#include "src/ast/scopes.h"
|
||||
@ -13,9 +15,7 @@
|
||||
#include "src/isolate.h"
|
||||
#include "src/objects.h"
|
||||
#include "src/parsing/parser.h"
|
||||
#include "src/typing-asm.h"
|
||||
|
||||
#include "src/wasm/asm-wasm-builder.h"
|
||||
#include "src/wasm/encoder.h"
|
||||
#include "src/wasm/module-decoder.h"
|
||||
#include "src/wasm/wasm-js.h"
|
||||
|
@ -92,7 +92,6 @@ static void GenerateTailCallToReturnedCode(MacroAssembler* masm,
|
||||
__ jmp(rbx);
|
||||
}
|
||||
|
||||
|
||||
void Builtins::Generate_InOptimizationQueue(MacroAssembler* masm) {
|
||||
// Checking whether the queued function is ready for install is optional,
|
||||
// since we come across interrupts and stack checks elsewhere. However,
|
||||
@ -1073,6 +1072,46 @@ void Builtins::Generate_CompileOptimizedConcurrent(MacroAssembler* masm) {
|
||||
GenerateTailCallToReturnedCode(masm, Runtime::kCompileOptimized_Concurrent);
|
||||
}
|
||||
|
||||
void Builtins::Generate_InstantiateAsmJs(MacroAssembler* masm) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- rax : argument count (preserved for callee)
|
||||
// -- rdx : new target (preserved for callee)
|
||||
// -- rdi : target function (preserved for callee)
|
||||
// -----------------------------------
|
||||
Label failed;
|
||||
{
|
||||
FrameScope scope(masm, StackFrame::INTERNAL);
|
||||
// Push the number of arguments to the callee.
|
||||
__ Integer32ToSmi(rax, rax);
|
||||
__ Push(rax);
|
||||
// Push a copy of the target function and the new target.
|
||||
__ Push(rdi);
|
||||
__ Push(rdx);
|
||||
|
||||
// The function.
|
||||
__ Push(rdi);
|
||||
// Copy arguments from caller (stdlib, foreign, heap).
|
||||
for (int i = 2; i >= 0; --i) {
|
||||
__ Push(Operand(
|
||||
rbp, StandardFrameConstants::kCallerSPOffset + i * kPointerSize));
|
||||
}
|
||||
// Call runtime, on success unwind frame, and parent frame.
|
||||
__ CallRuntime(Runtime::kInstantiateAsmJs, 4);
|
||||
// A smi 0 is returned on failure, an object on success.
|
||||
__ JumpIfSmi(rax, &failed, Label::kNear);
|
||||
scope.GenerateLeaveFrame();
|
||||
__ ret(4 * kPointerSize);
|
||||
|
||||
__ bind(&failed);
|
||||
// Restore target function and new target.
|
||||
__ Pop(rdx);
|
||||
__ Pop(rdi);
|
||||
__ Pop(rax);
|
||||
__ SmiToInteger32(rax, rax);
|
||||
}
|
||||
// On failure, tail call back to regular js.
|
||||
GenerateTailCallToReturnedCode(masm, Runtime::kCompileLazy);
|
||||
}
|
||||
|
||||
static void GenerateMakeCodeYoungAgainCommon(MacroAssembler* masm) {
|
||||
// For now, we are relying on the fact that make_code_young doesn't do any
|
||||
|
@ -1018,6 +1018,46 @@ void Builtins::Generate_CompileOptimizedConcurrent(MacroAssembler* masm) {
|
||||
GenerateTailCallToReturnedCode(masm, Runtime::kCompileOptimized_Concurrent);
|
||||
}
|
||||
|
||||
void Builtins::Generate_InstantiateAsmJs(MacroAssembler* masm) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- eax : argument count (preserved for callee)
|
||||
// -- edx : new target (preserved for callee)
|
||||
// -- edi : target function (preserved for callee)
|
||||
// -----------------------------------
|
||||
Label failed;
|
||||
{
|
||||
FrameScope scope(masm, StackFrame::INTERNAL);
|
||||
// Push the number of arguments to the callee.
|
||||
__ SmiTag(eax);
|
||||
__ push(eax);
|
||||
// Push a copy of the target function and the new target.
|
||||
__ push(edi);
|
||||
__ push(edx);
|
||||
|
||||
// The function.
|
||||
__ push(edi);
|
||||
// Copy arguments from caller (stdlib, foreign, heap).
|
||||
for (int i = 2; i >= 0; --i) {
|
||||
__ push(Operand(
|
||||
ebp, StandardFrameConstants::kCallerSPOffset + i * kPointerSize));
|
||||
}
|
||||
// Call runtime, on success unwind frame, and parent frame.
|
||||
__ CallRuntime(Runtime::kInstantiateAsmJs, 4);
|
||||
// A smi 0 is returned on failure, an object on success.
|
||||
__ JumpIfSmi(eax, &failed, Label::kNear);
|
||||
scope.GenerateLeaveFrame();
|
||||
__ ret(4 * kPointerSize);
|
||||
|
||||
__ bind(&failed);
|
||||
// Restore target function and new target.
|
||||
__ pop(edx);
|
||||
__ pop(edi);
|
||||
__ pop(eax);
|
||||
__ SmiUntag(eax);
|
||||
}
|
||||
// On failure, tail call back to regular js.
|
||||
GenerateTailCallToReturnedCode(masm, Runtime::kCompileLazy);
|
||||
}
|
||||
|
||||
static void GenerateMakeCodeYoungAgainCommon(MacroAssembler* masm) {
|
||||
// For now, we are relying on the fact that make_code_young doesn't do any
|
||||
|
@ -4,16 +4,16 @@
|
||||
|
||||
#include "src/v8.h"
|
||||
|
||||
#include "src/ast/ast.h"
|
||||
#include "src/asmjs/typing-asm.h"
|
||||
#include "src/ast/ast-expression-visitor.h"
|
||||
#include "src/ast/ast.h"
|
||||
#include "src/ast/scopes.h"
|
||||
#include "src/parsing/parser.h"
|
||||
#include "src/parsing/rewriter.h"
|
||||
#include "src/type-cache.h"
|
||||
#include "src/typing-asm.h"
|
||||
#include "test/cctest/cctest.h"
|
||||
#include "test/cctest/expression-type-collector.h"
|
||||
#include "test/cctest/expression-type-collector-macros.h"
|
||||
#include "test/cctest/expression-type-collector.h"
|
||||
|
||||
// Macros for function types.
|
||||
#define FUNC_FOREIGN_TYPE Bounds(Type::Function(Type::Any(), zone))
|
||||
|
@ -2,7 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "src/wasm/asm-types.h"
|
||||
#include "src/asmjs/asm-types.h"
|
||||
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
|
Loading…
Reference in New Issue
Block a user