blob: 6b2f32318bb7c6c2cf5725bc9383066bf94f73e2 [file] [log] [blame]
/*
* Copyright 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.gwt.dev.shell;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.dev.javac.JsniMethod;
import com.google.gwt.dev.shell.JsValue.DispatchObject;
import com.google.gwt.dev.util.log.speedtracer.DevModeEventType;
import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger;
import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger.Event;
import java.util.List;
import java.util.Set;
/**
*/
public class ModuleSpaceOOPHM extends ModuleSpace {
private BrowserChannelServer channel;
public ModuleSpaceOOPHM(ModuleSpaceHost msh, String moduleName,
BrowserChannelServer channel) {
super(msh.getLogger(), msh, moduleName);
this.channel = channel;
msh.getLogger().log(TreeLogger.DEBUG,
"Created ModuleSpaceOOPHM for " + moduleName, null);
}
public void createNativeMethods(TreeLogger logger,
List<JsniMethod> jsniMethods, DispatchIdOracle dispatchIdOracle) {
if (jsniMethods.isEmpty()) {
return;
}
StringBuilder jsni = new StringBuilder();
for (JsniMethod jsniMethod : jsniMethods) {
if (jsniMethod.isScriptOnly()) {
continue;
}
String body = Jsni.getJavaScriptForHostedMode(dispatchIdOracle,
jsniMethod);
if (body == null) {
// The error has been logged; just ignore it for now.
continue;
}
jsni.append("// " + jsniMethod.location() + ":" + jsniMethod.line()
+ "\n");
jsni.append("this[\"" + jsniMethod.name() + "\"] = function(");
String[] paramNames = jsniMethod.paramNames();
for (int i = 0; i < paramNames.length; ++i) {
if (i > 0) {
jsni.append(", ");
}
jsni.append(paramNames[i]);
}
jsni.append(") ");
jsni.append(body);
jsni.append(";\n\n");
}
channel.loadJsni(jsni.toString());
}
// @Override
protected void cleanupJsValues() {
Set<Integer> refIdsForCleanup = channel.getRefIdsForCleanup();
if (refIdsForCleanup.isEmpty()) {
// nothing to do
return;
}
int[] ids = new int[refIdsForCleanup.size()];
int i = 0;
for (Integer id : refIdsForCleanup) {
ids[i++] = id;
}
channel.freeJsValue(ids);
}
/**
*
*/
@Override
protected void createStaticDispatcher(TreeLogger logger) {
channel.loadJsni("function __defineStatic(__arg0) { window.__static = __arg0; }");
}
/**
* Invoke a JS method and return its value.
*
* @param name method name to invoke
* @param jthis object to invoke method on, null if static method
* @param types argument types
* @param args argument values
*/
@Override
protected JsValue doInvoke(String name, Object jthis, Class<?>[] types,
Object[] args) throws Throwable {
TreeLogger branch = host.getLogger().branch(TreeLogger.SPAM,
"Invoke native method " + name, null);
Event javaToJsCallEvent =
SpeedTracerLogger.start(DevModeEventType.JAVA_TO_JS_CALL);
if (SpeedTracerLogger.jsniCallLoggingEnabled()) {
javaToJsCallEvent.addData("name", name);
}
CompilingClassLoader isolatedClassLoader = getIsolatedClassLoader();
JsValueOOPHM jsthis = new JsValueOOPHM();
Class<?> jthisType = (jthis == null) ? Object.class : jthis.getClass();
JsValueGlue.set(jsthis, isolatedClassLoader, jthisType, jthis);
if (branch.isLoggable(TreeLogger.SPAM)) {
branch.log(TreeLogger.SPAM, " this=" + jsthis);
}
int argc = args.length;
JsValueOOPHM argv[] = new JsValueOOPHM[argc];
for (int i = 0; i < argc; ++i) {
argv[i] = new JsValueOOPHM();
JsValueGlue.set(argv[i], isolatedClassLoader, types[i], args[i]);
if (branch.isLoggable(TreeLogger.SPAM)) {
branch.log(TreeLogger.SPAM, " arg[" + i + "]=" + argv[i]);
}
}
JsValueOOPHM returnVal = new JsValueOOPHM();
try {
channel.invokeJavascript(isolatedClassLoader, jsthis, name, argv,
returnVal);
if (branch.isLoggable(TreeLogger.SPAM)) {
branch.log(TreeLogger.SPAM, " returned " + returnVal);
}
return returnVal;
} catch (Throwable t) {
branch.log(TreeLogger.SPAM, "exception thrown", t);
throw t;
} finally {
javaToJsCallEvent.end();
}
}
@Override
protected DispatchObject getStaticDispatcher() {
return new JsValueOOPHM.DispatchObjectOOPHM(getIsolatedClassLoader());
}
}