Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(20)

Side by Side Diff: src/wasm/wasm-js.cc

Issue 1581913005: Allow asm modules to be instatiated with external heaps. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: fix Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | test/mjsunit/wasm/asm-wasm.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/api.h" 5 #include "src/api.h"
6 #include "src/api-natives.h" 6 #include "src/api-natives.h"
7 #include "src/assert-scope.h" 7 #include "src/assert-scope.h"
8 #include "src/ast/ast.h" 8 #include "src/ast/ast.h"
9 #include "src/ast/scopes.h" 9 #include "src/ast/scopes.h"
10 #include "src/factory.h" 10 #include "src/factory.h"
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 } else { 119 } else {
120 // Success. Compile and run! 120 // Success. Compile and run!
121 int32_t retval = i::wasm::CompileAndRunWasmModule(isolate, result.val); 121 int32_t retval = i::wasm::CompileAndRunWasmModule(isolate, result.val);
122 args.GetReturnValue().Set(retval); 122 args.GetReturnValue().Set(retval);
123 } 123 }
124 124
125 if (result.val) delete result.val; 125 if (result.val) delete result.val;
126 } 126 }
127 127
128 128
129 v8::internal::wasm::WasmModuleIndex* TranslateAsmModule(i::ParseInfo* info) { 129 v8::internal::wasm::WasmModuleIndex* TranslateAsmModule(i::ParseInfo* info,
130 ErrorThrower* thrower) {
130 info->set_global(); 131 info->set_global();
131 info->set_lazy(false); 132 info->set_lazy(false);
132 info->set_allow_lazy_parsing(false); 133 info->set_allow_lazy_parsing(false);
133 info->set_toplevel(true); 134 info->set_toplevel(true);
134 135
135 if (!i::Compiler::ParseAndAnalyze(info)) { 136 if (!i::Compiler::ParseAndAnalyze(info)) {
136 return nullptr; 137 return nullptr;
137 } 138 }
138 139
139 info->set_literal( 140 info->set_literal(
140 info->scope()->declarations()->at(0)->AsFunctionDeclaration()->fun()); 141 info->scope()->declarations()->at(0)->AsFunctionDeclaration()->fun());
141 142
142 v8::internal::AsmTyper typer(info->isolate(), info->zone(), *(info->script()), 143 v8::internal::AsmTyper typer(info->isolate(), info->zone(), *(info->script()),
143 info->literal()); 144 info->literal());
144 if (!typer.Validate()) { 145 if (!typer.Validate()) {
146 thrower->Error("Asm.js validation failed: %s", typer.error_message());
145 return nullptr; 147 return nullptr;
146 } 148 }
147 149
148 auto module = v8::internal::wasm::AsmWasmBuilder( 150 auto module = v8::internal::wasm::AsmWasmBuilder(
149 info->isolate(), info->zone(), info->literal()) 151 info->isolate(), info->zone(), info->literal())
150 .Run(); 152 .Run();
151 return module; 153 return module;
152 } 154 }
153 155
154 156
155 void AsmCompileRun(const v8::FunctionCallbackInfo<v8::Value>& args) { 157 void AsmCompileRun(const v8::FunctionCallbackInfo<v8::Value>& args) {
156 HandleScope scope(args.GetIsolate()); 158 HandleScope scope(args.GetIsolate());
157 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); 159 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate());
158 ErrorThrower thrower(isolate, "WASM.asmCompileRun()"); 160 ErrorThrower thrower(isolate, "WASM.asmCompileRun()");
159 161
160 if (args.Length() != 1) { 162 if (args.Length() != 1) {
161 thrower.Error("Invalid argument count"); 163 thrower.Error("Invalid argument count");
162 return; 164 return;
163 } 165 }
164 if (!args[0]->IsString()) { 166 if (!args[0]->IsString()) {
165 thrower.Error("Invalid argument count"); 167 thrower.Error("Asm module text should be a string");
166 return; 168 return;
167 } 169 }
168 170
169 i::Factory* factory = isolate->factory(); 171 i::Factory* factory = isolate->factory();
170 i::Zone zone; 172 i::Zone zone;
171 Local<String> source = Local<String>::Cast(args[0]); 173 Local<String> source = Local<String>::Cast(args[0]);
172 i::Handle<i::Script> script = factory->NewScript(Utils::OpenHandle(*source)); 174 i::Handle<i::Script> script = factory->NewScript(Utils::OpenHandle(*source));
173 i::ParseInfo info(&zone, script); 175 i::ParseInfo info(&zone, script);
174 176
175 auto module = TranslateAsmModule(&info); 177 auto module = TranslateAsmModule(&info, &thrower);
176 if (module == nullptr) { 178 if (module == nullptr) {
177 thrower.Error("Asm.js validation failed");
178 return; 179 return;
179 } 180 }
180 181
181 int32_t result = v8::internal::wasm::CompileAndRunWasmModule( 182 int32_t result = v8::internal::wasm::CompileAndRunWasmModule(
182 isolate, module->Begin(), module->End(), true); 183 isolate, module->Begin(), module->End(), true);
183 args.GetReturnValue().Set(result); 184 args.GetReturnValue().Set(result);
184 } 185 }
185 186
186 187
187 // TODO(aseemgarg): deal with arraybuffer and foreign functions 188 void InstantiateModuleCommon(const v8::FunctionCallbackInfo<v8::Value>& args,
188 void InstantiateModuleFromAsm(const v8::FunctionCallbackInfo<v8::Value>& args) { 189 const byte* start, const byte* end,
189 HandleScope scope(args.GetIsolate()); 190 ErrorThrower* thrower, bool must_decode) {
190 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); 191 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate());
191 ErrorThrower thrower(isolate, "WASM.instantiateModuleFromAsm()");
192 192
193 if (args.Length() != 1) { 193 i::Handle<i::JSArrayBuffer> memory = i::Handle<i::JSArrayBuffer>::null();
194 thrower.Error("Invalid argument count"); 194 if (args.Length() > 2 && args[2]->IsArrayBuffer()) {
195 return; 195 Local<Object> obj = Local<Object>::Cast(args[2]);
196 } 196 i::Handle<i::Object> mem_obj = v8::Utils::OpenHandle(*obj);
197 if (!args[0]->IsString()) { 197 memory = i::Handle<i::JSArrayBuffer>(i::JSArrayBuffer::cast(*mem_obj));
198 thrower.Error("Invalid argument count");
199 return;
200 } 198 }
201 199
202 i::Factory* factory = isolate->factory(); 200 // Decode but avoid a redundant pass over function bodies for verification.
201 // Verification will happen during compilation.
203 i::Zone zone; 202 i::Zone zone;
204 Local<String> source = Local<String>::Cast(args[0]); 203 internal::wasm::ModuleResult result = internal::wasm::DecodeWasmModule(
205 i::Handle<i::Script> script = factory->NewScript(Utils::OpenHandle(*source)); 204 isolate, &zone, start, end, false, false);
206 i::ParseInfo info(&zone, script);
207 205
208 auto module = TranslateAsmModule(&info); 206 if (result.failed() && must_decode) {
209 if (module == nullptr) { 207 thrower->Error("Asm.js converted module failed to decode");
210 thrower.Error("Asm.js validation failed"); 208 } else if (result.failed()) {
211 return; 209 thrower->Failed("", result);
212 }
213
214 i::Handle<i::JSArrayBuffer> memory = i::Handle<i::JSArrayBuffer>::null();
215 internal::wasm::ModuleResult result = internal::wasm::DecodeWasmModule(
216 isolate, &zone, module->Begin(), module->End(), false, false);
217
218 if (result.failed()) {
219 thrower.Failed("", result);
220 } else { 210 } else {
221 // Success. Instantiate the module and return the object. 211 // Success. Instantiate the module and return the object.
222 i::Handle<i::JSObject> ffi = i::Handle<i::JSObject>::null(); 212 i::Handle<i::JSObject> ffi = i::Handle<i::JSObject>::null();
213 if (args.Length() > 1 && args[1]->IsObject()) {
214 Local<Object> obj = Local<Object>::Cast(args[1]);
215 ffi = i::Handle<i::JSObject>::cast(v8::Utils::OpenHandle(*obj));
216 }
223 217
224 i::MaybeHandle<i::JSObject> object = 218 i::MaybeHandle<i::JSObject> object =
225 result.val->Instantiate(isolate, ffi, memory); 219 result.val->Instantiate(isolate, ffi, memory);
226 220
227 if (!object.is_null()) { 221 if (!object.is_null()) {
228 args.GetReturnValue().Set(v8::Utils::ToLocal(object.ToHandleChecked())); 222 args.GetReturnValue().Set(v8::Utils::ToLocal(object.ToHandleChecked()));
229 } 223 }
230 } 224 }
231 225
232 if (result.val) delete result.val; 226 if (result.val) delete result.val;
233 } 227 }
234 228
235 229
230 void InstantiateModuleFromAsm(const v8::FunctionCallbackInfo<v8::Value>& args) {
231 HandleScope scope(args.GetIsolate());
232 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate());
233 ErrorThrower thrower(isolate, "WASM.instantiateModuleFromAsm()");
234
235 if (!args[0]->IsString()) {
236 thrower.Error("Asm module text should be a string");
237 return;
238 }
239
240 i::Factory* factory = isolate->factory();
241 i::Zone zone;
242 Local<String> source = Local<String>::Cast(args[0]);
243 i::Handle<i::Script> script = factory->NewScript(Utils::OpenHandle(*source));
244 i::ParseInfo info(&zone, script);
245
246 auto module = TranslateAsmModule(&info, &thrower);
247 if (module == nullptr) {
248 return;
249 }
250
251 InstantiateModuleCommon(args, module->Begin(), module->End(), &thrower, true);
252 }
253
254
236 void InstantiateModule(const v8::FunctionCallbackInfo<v8::Value>& args) { 255 void InstantiateModule(const v8::FunctionCallbackInfo<v8::Value>& args) {
237 HandleScope scope(args.GetIsolate()); 256 HandleScope scope(args.GetIsolate());
238 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); 257 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate());
239 ErrorThrower thrower(isolate, "WASM.instantiateModule()"); 258 ErrorThrower thrower(isolate, "WASM.instantiateModule()");
240 259
241 RawBuffer buffer = GetRawBufferArgument(thrower, args); 260 RawBuffer buffer = GetRawBufferArgument(thrower, args);
242 if (buffer.start == nullptr) return; 261 if (buffer.start == nullptr) return;
243 262
244 i::Handle<i::JSArrayBuffer> memory = i::Handle<i::JSArrayBuffer>::null(); 263 InstantiateModuleCommon(args, buffer.start, buffer.end, &thrower, false);
245 if (args.Length() > 2 && args[2]->IsArrayBuffer()) {
246 Local<Object> obj = Local<Object>::Cast(args[2]);
247 i::Handle<i::Object> mem_obj = v8::Utils::OpenHandle(*obj);
248 memory = i::Handle<i::JSArrayBuffer>(i::JSArrayBuffer::cast(*mem_obj));
249 }
250
251 // Decode but avoid a redundant pass over function bodies for verification.
252 // Verification will happen during compilation.
253 i::Zone zone;
254 internal::wasm::ModuleResult result = internal::wasm::DecodeWasmModule(
255 isolate, &zone, buffer.start, buffer.end, false, false);
256
257 if (result.failed()) {
258 thrower.Failed("", result);
259 } else {
260 // Success. Instantiate the module and return the object.
261 i::Handle<i::JSObject> ffi = i::Handle<i::JSObject>::null();
262 if (args.Length() > 1 && args[1]->IsObject()) {
263 Local<Object> obj = Local<Object>::Cast(args[1]);
264 ffi = i::Handle<i::JSObject>::cast(v8::Utils::OpenHandle(*obj));
265 }
266
267 i::MaybeHandle<i::JSObject> object =
268 result.val->Instantiate(isolate, ffi, memory);
269
270 if (!object.is_null()) {
271 args.GetReturnValue().Set(v8::Utils::ToLocal(object.ToHandleChecked()));
272 }
273 }
274
275 if (result.val) delete result.val;
276 } 264 }
277 } // namespace 265 } // namespace
278 266
279 267
280 // TODO(titzer): we use the API to create the function template because the 268 // TODO(titzer): we use the API to create the function template because the
281 // internal guts are too ugly to replicate here. 269 // internal guts are too ugly to replicate here.
282 static i::Handle<i::FunctionTemplateInfo> NewTemplate(i::Isolate* i_isolate, 270 static i::Handle<i::FunctionTemplateInfo> NewTemplate(i::Isolate* i_isolate,
283 FunctionCallback func) { 271 FunctionCallback func) {
284 Isolate* isolate = reinterpret_cast<Isolate*>(i_isolate); 272 Isolate* isolate = reinterpret_cast<Isolate*>(i_isolate);
285 Local<FunctionTemplate> local = FunctionTemplate::New(isolate, func); 273 Local<FunctionTemplate> local = FunctionTemplate::New(isolate, func);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 if (!context->get(Context::WASM_FUNCTION_MAP_INDEX)->IsMap()) { 324 if (!context->get(Context::WASM_FUNCTION_MAP_INDEX)->IsMap()) {
337 Handle<Map> wasm_function_map = isolate->factory()->NewMap( 325 Handle<Map> wasm_function_map = isolate->factory()->NewMap(
338 JS_FUNCTION_TYPE, JSFunction::kSize + kPointerSize); 326 JS_FUNCTION_TYPE, JSFunction::kSize + kPointerSize);
339 wasm_function_map->set_is_callable(); 327 wasm_function_map->set_is_callable();
340 context->set_wasm_function_map(*wasm_function_map); 328 context->set_wasm_function_map(*wasm_function_map);
341 } 329 }
342 } 330 }
343 331
344 } // namespace internal 332 } // namespace internal
345 } // namespace v8 333 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | test/mjsunit/wasm/asm-wasm.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698