aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore20
-rw-r--r--INSTALL-WIN32.md256
-rw-r--r--INSTALL.md282
-rw-r--r--Makefile.in43
-rw-r--r--README.md.txt266
-rw-r--r--TAR.include1
-rw-r--r--configure.in21
-rw-r--r--erts/configure.in27
-rw-r--r--erts/doc/src/alt_dist.xml8
-rw-r--r--erts/doc/src/driver.xml2
-rw-r--r--erts/doc/src/erl_dist_protocol.xml2
-rw-r--r--erts/doc/src/erl_driver.xml2
-rw-r--r--erts/doc/src/erlang.xml24
-rw-r--r--erts/doc/src/escript.xml217
-rw-r--r--erts/doc/src/notes.xml2
-rw-r--r--erts/emulator/beam/atom.names1
-rw-r--r--erts/emulator/beam/beam_bif_load.c38
-rw-r--r--erts/emulator/beam/beam_bp.c213
-rw-r--r--erts/emulator/beam/beam_bp.h50
-rw-r--r--erts/emulator/beam/beam_catches.c18
-rw-r--r--erts/emulator/beam/beam_catches.h16
-rw-r--r--erts/emulator/beam/beam_debug.c154
-rw-r--r--erts/emulator/beam/beam_emu.c518
-rw-r--r--erts/emulator/beam/beam_load.c408
-rw-r--r--erts/emulator/beam/beam_load.h22
-rw-r--r--erts/emulator/beam/bif.c19
-rw-r--r--erts/emulator/beam/bif.h31
-rw-r--r--erts/emulator/beam/big.c74
-rw-r--r--erts/emulator/beam/big.h24
-rw-r--r--erts/emulator/beam/binary.c2
-rw-r--r--erts/emulator/beam/break.c12
-rw-r--r--erts/emulator/beam/dist.c173
-rw-r--r--erts/emulator/beam/dist.h11
-rw-r--r--erts/emulator/beam/erl_alloc.c96
-rw-r--r--erts/emulator/beam/erl_alloc.h18
-rw-r--r--erts/emulator/beam/erl_alloc.types14
-rw-r--r--erts/emulator/beam/erl_alloc_util.c175
-rw-r--r--erts/emulator/beam/erl_alloc_util.h60
-rw-r--r--erts/emulator/beam/erl_arith.c107
-rw-r--r--erts/emulator/beam/erl_async.c14
-rw-r--r--erts/emulator/beam/erl_bif_chksum.c14
-rw-r--r--erts/emulator/beam/erl_bif_info.c35
-rw-r--r--erts/emulator/beam/erl_bif_lists.c15
-rw-r--r--erts/emulator/beam/erl_bif_op.c12
-rw-r--r--erts/emulator/beam/erl_bif_port.c14
-rw-r--r--erts/emulator/beam/erl_bif_re.c8
-rw-r--r--erts/emulator/beam/erl_bif_timer.c20
-rw-r--r--erts/emulator/beam/erl_bif_trace.c57
-rw-r--r--erts/emulator/beam/erl_binary.h2
-rw-r--r--erts/emulator/beam/erl_bits.c14
-rw-r--r--erts/emulator/beam/erl_bits.h12
-rw-r--r--erts/emulator/beam/erl_db.c135
-rw-r--r--erts/emulator/beam/erl_db_hash.c12
-rw-r--r--erts/emulator/beam/erl_db_tree.c12
-rw-r--r--erts/emulator/beam/erl_db_util.c340
-rw-r--r--erts/emulator/beam/erl_db_util.h18
-rw-r--r--erts/emulator/beam/erl_debug.c28
-rw-r--r--erts/emulator/beam/erl_debug.h18
-rw-r--r--erts/emulator/beam/erl_driver.h11
-rw-r--r--erts/emulator/beam/erl_fun.c18
-rw-r--r--erts/emulator/beam/erl_fun.h18
-rw-r--r--erts/emulator/beam/erl_gc.c6
-rw-r--r--erts/emulator/beam/erl_goodfit_alloc.c58
-rw-r--r--erts/emulator/beam/erl_goodfit_alloc.h30
-rw-r--r--erts/emulator/beam/erl_instrument.c84
-rw-r--r--erts/emulator/beam/erl_lock_check.c5
-rw-r--r--erts/emulator/beam/erl_message.h2
-rw-r--r--erts/emulator/beam/erl_mtrace.c36
-rw-r--r--erts/emulator/beam/erl_nif.c64
-rw-r--r--erts/emulator/beam/erl_nif.h30
-rw-r--r--erts/emulator/beam/erl_node_container_utils.h12
-rw-r--r--erts/emulator/beam/erl_node_tables.c39
-rw-r--r--erts/emulator/beam/erl_node_tables.h12
-rw-r--r--erts/emulator/beam/erl_printf_term.c16
-rw-r--r--erts/emulator/beam/erl_process.c60
-rw-r--r--erts/emulator/beam/erl_process.h40
-rw-r--r--erts/emulator/beam/erl_process_dump.c32
-rw-r--r--erts/emulator/beam/erl_term.c28
-rw-r--r--erts/emulator/beam/erl_term.h85
-rw-r--r--erts/emulator/beam/erl_trace.c247
-rw-r--r--erts/emulator/beam/erl_unicode.c30
-rw-r--r--erts/emulator/beam/erl_vm.h13
-rw-r--r--erts/emulator/beam/error.h16
-rw-r--r--erts/emulator/beam/export.c20
-rw-r--r--erts/emulator/beam/export.h16
-rw-r--r--erts/emulator/beam/external.c162
-rw-r--r--erts/emulator/beam/external.h2
-rw-r--r--erts/emulator/beam/global.h132
-rw-r--r--erts/emulator/beam/io.c234
-rw-r--r--erts/emulator/beam/module.h4
-rw-r--r--erts/emulator/beam/sys.h55
-rw-r--r--erts/emulator/beam/utils.c176
-rw-r--r--erts/emulator/drivers/common/efile_drv.c26
-rw-r--r--erts/emulator/drivers/unix/ttsl_drv.c6
-rw-r--r--erts/emulator/sys/common/erl_mseg.c467
-rw-r--r--erts/emulator/sys/common/erl_mseg.h14
-rw-r--r--erts/emulator/test/driver_SUITE_data/peek_non_existing_queue_drv.c2
-rw-r--r--erts/emulator/test/obsolete_SUITE.erl14
-rw-r--r--erts/emulator/test/system_info_SUITE.erl24
-rwxr-xr-xerts/emulator/utils/beam_makeops22
-rwxr-xr-xerts/emulator/utils/make_tables20
-rw-r--r--erts/include/erl_int_sizes_config.h.in13
-rw-r--r--erts/preloaded/ebin/erl_prim_loader.beambin50808 -> 50816 bytes
-rw-r--r--erts/preloaded/ebin/erlang.beambin23800 -> 23808 bytes
-rw-r--r--erts/preloaded/ebin/init.beambin44488 -> 44500 bytes
-rw-r--r--erts/preloaded/ebin/otp_ring0.beambin1436 -> 1448 bytes
-rw-r--r--erts/preloaded/ebin/prim_file.beambin29480 -> 29496 bytes
-rw-r--r--erts/preloaded/ebin/prim_inet.beambin57308 -> 57320 bytes
-rw-r--r--erts/preloaded/ebin/prim_zip.beambin21756 -> 22600 bytes
-rw-r--r--erts/preloaded/ebin/zlib.beambin10612 -> 10620 bytes
-rw-r--r--erts/preloaded/src/prim_zip.erl89
-rw-r--r--lib/appmon/doc/src/appmon_chapter.xml10
-rw-r--r--lib/asn1/test/Makefile18
-rw-r--r--lib/asn1/test/asn1_SUITE.erl.src2
-rw-r--r--lib/asn1/test/asn1_app_test.erl38
-rw-r--r--lib/asn1/test/asn1_appup_test.erl56
-rw-r--r--lib/asn1/test/asn1_test_lib.erl2
-rw-r--r--lib/asn1/test/asn1_wrapper.erl20
-rw-r--r--lib/asn1/test/ber_decode_error.erl12
-rw-r--r--lib/asn1/test/choice_extension.erl12
-rw-r--r--lib/asn1/test/h323test.erl12
-rw-r--r--lib/asn1/test/testChoExtension.erl12
-rw-r--r--lib/asn1/test/testChoExternal.erl12
-rw-r--r--lib/asn1/test/testChoOptional.erl12
-rw-r--r--lib/asn1/test/testChoOptionalImplicitTag.erl12
-rw-r--r--lib/asn1/test/testChoPrim.erl12
-rw-r--r--lib/asn1/test/testChoRecursive.erl12
-rw-r--r--lib/asn1/test/testChoTypeRefCho.erl12
-rw-r--r--lib/asn1/test/testChoTypeRefPrim.erl12
-rw-r--r--lib/asn1/test/testChoTypeRefSeq.erl12
-rw-r--r--lib/asn1/test/testChoTypeRefSet.erl12
-rw-r--r--lib/asn1/test/testChoiceIndefinite.erl12
-rw-r--r--lib/asn1/test/testCompactBitString.erl12
-rw-r--r--lib/asn1/test/testConstraints.erl12
-rw-r--r--lib/asn1/test/testContextSwitchingTypes.erl16
-rw-r--r--lib/asn1/test/testDER.erl12
-rw-r--r--lib/asn1/test/testDeepTConstr.erl12
-rw-r--r--lib/asn1/test/testDef.erl12
-rw-r--r--lib/asn1/test/testDoubleEllipses.erl12
-rw-r--r--lib/asn1/test/testEnumExt.erl12
-rw-r--r--lib/asn1/test/testExternal.erl12
-rw-r--r--lib/asn1/test/testINSTANCE_OF.erl24
-rw-r--r--lib/asn1/test/testInfObj.erl12
-rw-r--r--lib/asn1/test/testInfObjectClass.erl12
-rw-r--r--lib/asn1/test/testMegaco.erl14
-rw-r--r--lib/asn1/test/testMergeCompile.erl12
-rw-r--r--lib/asn1/test/testMvrasn6.erl12
-rw-r--r--lib/asn1/test/testNBAPsystem.erl14
-rw-r--r--lib/asn1/test/testOpenTypeImplicitTag.erl12
-rw-r--r--lib/asn1/test/testOpt.erl12
-rw-r--r--lib/asn1/test/testParamBasic.erl12
-rw-r--r--lib/asn1/test/testParameterizedInfObj.erl2
-rw-r--r--lib/asn1/test/testPrim.erl12
-rw-r--r--lib/asn1/test/testPrimExternal.erl12
-rw-r--r--lib/asn1/test/testPrimStrings.erl14
-rw-r--r--lib/asn1/test/testRANAP.erl2
-rw-r--r--lib/asn1/test/testROSE.erl12
-rw-r--r--lib/asn1/test/testSSLspecs.erl12
-rw-r--r--lib/asn1/test/testSelectionTypes.erl12
-rw-r--r--lib/asn1/test/testSeq2738.erl12
-rw-r--r--lib/asn1/test/testSeqDefault.erl12
-rw-r--r--lib/asn1/test/testSeqExtension.erl12
-rw-r--r--lib/asn1/test/testSeqExternal.erl12
-rw-r--r--lib/asn1/test/testSeqIndefinite.erl12
-rw-r--r--lib/asn1/test/testSeqOf.erl12
-rw-r--r--lib/asn1/test/testSeqOfCho.erl12
-rw-r--r--lib/asn1/test/testSeqOfExternal.erl12
-rw-r--r--lib/asn1/test/testSeqOfIndefinite.erl12
-rw-r--r--lib/asn1/test/testSeqOfTag.erl12
-rw-r--r--lib/asn1/test/testSeqOptional.erl12
-rw-r--r--lib/asn1/test/testSeqPrim.erl12
-rw-r--r--lib/asn1/test/testSeqSetDefaultVal.erl12
-rw-r--r--lib/asn1/test/testSeqTag.erl12
-rw-r--r--lib/asn1/test/testSeqTypeRefCho.erl12
-rw-r--r--lib/asn1/test/testSeqTypeRefPrim.erl12
-rw-r--r--lib/asn1/test/testSeqTypeRefSeq.erl12
-rw-r--r--lib/asn1/test/testSeqTypeRefSet.erl12
-rw-r--r--lib/asn1/test/testSetDefault.erl12
-rw-r--r--lib/asn1/test/testSetExtension.erl12
-rw-r--r--lib/asn1/test/testSetExternal.erl12
-rw-r--r--lib/asn1/test/testSetIndefinite.erl12
-rw-r--r--lib/asn1/test/testSetOf.erl12
-rw-r--r--lib/asn1/test/testSetOfCho.erl12
-rw-r--r--lib/asn1/test/testSetOfExternal.erl12
-rw-r--r--lib/asn1/test/testSetOfTag.erl12
-rw-r--r--lib/asn1/test/testSetOptional.erl12
-rw-r--r--lib/asn1/test/testSetPrim.erl12
-rw-r--r--lib/asn1/test/testSetTag.erl12
-rw-r--r--lib/asn1/test/testSetTypeRefCho.erl12
-rw-r--r--lib/asn1/test/testSetTypeRefPrim.erl12
-rw-r--r--lib/asn1/test/testSetTypeRefSeq.erl12
-rw-r--r--lib/asn1/test/testSetTypeRefSet.erl12
-rw-r--r--lib/asn1/test/testTCAP.erl12
-rw-r--r--lib/asn1/test/testTcapsystem.erl12
-rw-r--r--lib/asn1/test/testTimer.erl16
-rw-r--r--lib/asn1/test/testTypeValueNotation.erl12
-rw-r--r--lib/asn1/test/testX420.erl14
-rw-r--r--lib/asn1/test/test_bad_values.erl12
-rw-r--r--lib/asn1/test/test_compile_options.erl12
-rw-r--r--lib/asn1/test/test_driver_load.erl12
-rw-r--r--lib/asn1/test/test_inline.erl12
-rw-r--r--lib/asn1/test/test_modified_x420.erl12
-rw-r--r--lib/asn1/test/test_partial_incomplete_decode.erl12
-rw-r--r--lib/asn1/test/test_selective_decode.erl12
-rw-r--r--lib/asn1/test/test_special_decode_performance.erl12
-rw-r--r--lib/asn1/test/test_undecoded_rest.erl18
-rw-r--r--lib/asn1/test/test_x691.erl12
-rw-r--r--lib/compiler/src/v3_life.erl46
-rw-r--r--lib/cosTransactions/doc/src/ch_example.xml10
-rw-r--r--lib/erl_interface/doc/src/ei.xml8
-rw-r--r--lib/erl_interface/doc/src/erl_call.xml8
-rw-r--r--lib/hipe/cerl/erl_bif_types.erl2
-rw-r--r--lib/ic/doc/src/ch_c_mapping.xml8
-rw-r--r--lib/inets/doc/src/http_server.xml2
-rw-r--r--lib/inets/doc/src/httpc.xml3
-rw-r--r--lib/inets/doc/src/httpd_util.xml4
-rw-r--r--lib/inets/doc/src/mod_security.xml17
-rw-r--r--lib/inets/doc/src/notes.xml64
-rw-r--r--lib/inets/src/http_client/httpc_handler.erl35
-rw-r--r--lib/inets/src/http_server/httpd_conf.erl2
-rw-r--r--lib/inets/src/http_server/mod_esi.erl26
-rw-r--r--lib/inets/src/inets_app/inets.appup.src12
-rw-r--r--lib/inets/vsn.mk6
-rw-r--r--lib/kernel/doc/src/application.xml8
-rw-r--r--lib/kernel/doc/src/erl_ddll.xml12
-rw-r--r--lib/kernel/doc/src/file.xml19
-rw-r--r--lib/kernel/src/global.erl131
-rw-r--r--lib/kernel/test/global_SUITE.erl41
-rw-r--r--lib/megaco/doc/src/megaco_mib.xml12
-rw-r--r--lib/megaco/doc/src/megaco_run.xml8
-rw-r--r--lib/megaco/doc/src/megaco_user.xml8
-rw-r--r--lib/megaco/doc/src/notes_history.xml10
-rw-r--r--lib/megaco/test/megaco_app_test.erl14
-rw-r--r--lib/reltool/src/Makefile12
-rw-r--r--lib/reltool/src/reltool.erl154
-rw-r--r--lib/reltool/src/reltool.hrl335
-rw-r--r--lib/reltool/src/reltool_app_win.erl248
-rw-r--r--lib/reltool/src/reltool_fgraph.erl34
-rw-r--r--lib/reltool/src/reltool_fgraph_win.erl277
-rw-r--r--lib/reltool/src/reltool_mod_win.erl239
-rw-r--r--lib/reltool/src/reltool_server.erl809
-rw-r--r--lib/reltool/src/reltool_sys_win.erl389
-rw-r--r--lib/reltool/src/reltool_target.erl423
-rw-r--r--lib/reltool/src/reltool_utils.erl61
-rw-r--r--lib/runtime_tools/doc/src/erts_alloc_config.xml8
-rw-r--r--lib/runtime_tools/src/dbg.erl71
-rw-r--r--lib/snmp/doc/src/notes_history.xml14
-rw-r--r--lib/snmp/doc/src/snmp_app.xml4
-rw-r--r--lib/snmp/doc/src/snmp_config.xml2
-rw-r--r--lib/snmp/doc/src/snmpa_network_interface_filter.xml8
-rw-r--r--lib/snmp/doc/src/snmpm.xml10
-rw-r--r--lib/ssh/doc/src/notes.xml24
-rw-r--r--lib/ssh/doc/src/ssh.xml17
-rw-r--r--lib/ssh/src/ssh.appup.src16
-rw-r--r--lib/ssh/src/ssh.erl16
-rw-r--r--lib/ssh/src/ssh_connection.erl12
-rw-r--r--lib/ssh/src/ssh_connection_manager.erl22
-rw-r--r--lib/ssh/vsn.mk8
-rw-r--r--lib/ssl/doc/src/notes.xml15
-rw-r--r--lib/ssl/src/ssl.appup.src5
-rw-r--r--lib/ssl/src/ssl_certificate_db.erl2
-rw-r--r--lib/ssl/vsn.mk5
-rw-r--r--lib/stdlib/doc/src/io_protocol.xml4
-rw-r--r--lib/stdlib/doc/src/ms_transform.xml8
-rw-r--r--lib/stdlib/doc/src/unicode_usage.xml4
-rw-r--r--lib/stdlib/doc/src/zip.xml90
-rw-r--r--lib/stdlib/src/erl_expand_records.erl14
-rw-r--r--lib/stdlib/src/erl_lint.erl41
-rw-r--r--lib/stdlib/src/erl_parse.yrl37
-rw-r--r--lib/stdlib/src/escript.erl441
-rw-r--r--lib/stdlib/src/zip.erl80
-rw-r--r--lib/stdlib/test/erl_pp_SUITE.erl39
-rw-r--r--lib/stdlib/test/escript_SUITE.erl396
-rw-r--r--lib/stdlib/test/zip_SUITE.erl78
-rw-r--r--lib/test_server/doc/src/test_server_ctrl.xml2
-rw-r--r--lib/tools/emacs/test.erl.indented10
-rw-r--r--lib/tools/emacs/test.erl.orig10
-rw-r--r--lib/wx/c_src/wxe_driver.c13
-rw-r--r--lib/wx/c_src/wxe_driver.h11
-rw-r--r--lib/wx/c_src/wxe_impl.cpp16
-rw-r--r--lib/wx/c_src/wxe_impl.h15
-rw-r--r--lib/xmerl/doc/src/notes.xml2
-rw-r--r--make/emd2exml.in1285
-rwxr-xr-xotp_build2
-rw-r--r--system/doc/efficiency_guide/advanced.xml11
-rw-r--r--system/doc/efficiency_guide/commoncaveats.xml8
-rw-r--r--system/doc/efficiency_guide/functions.xml10
-rw-r--r--system/doc/efficiency_guide/myths.xml4
-rw-r--r--system/doc/getting_started/robustness.xml8
-rw-r--r--system/doc/installation_guide/Makefile45
-rw-r--r--system/doc/installation_guide/install-binary.xml (renamed from system/doc/installation_guide/install.xml)24
-rw-r--r--system/doc/installation_guide/make.dep2
-rw-r--r--system/doc/installation_guide/part.xml11
-rw-r--r--system/doc/installation_guide/xmlfiles.mk17
-rw-r--r--xcomp/README.md161
295 files changed, 9892 insertions, 4688 deletions
diff --git a/.gitignore b/.gitignore
index 1a68d55eff..48ec7cba82 100644
--- a/.gitignore
+++ b/.gitignore
@@ -51,6 +51,7 @@ a.out.dSYM/
/release
+/make/emd2exml
# Created by "out_build update_primary"
/bootstrap/primary_compiler/
@@ -103,6 +104,9 @@ a.out.dSYM/
# asn1
/lib/asn1/doc/src/asn1_spec.xml
+/lib/asn1/test/asn1_SUITE.erl
+/lib/asn1/test/asn1_bin_SUITE.erl
+/lib/asn1/test/asn1_bin_v2_SUITE.erl
# common_test
@@ -137,6 +141,13 @@ a.out.dSYM/
/erts/doc/pdf/*.pdf
/erts/doc/man[0-9]/*.[0-9]
+# et
+
+/lib/et/doc/html/*.png
+/lib/et/doc/src/et_desc.xml
+/lib/et/doc/src/et_examples.xml
+/lib/et/doc/src/et_tutorial.xml
+
# gs
/lib/gs/src/gstk_generic.hrl
@@ -162,6 +173,7 @@ a.out.dSYM/
/lib/ic/priv/ic.jar
/lib/ic/src/icparse.erl
/lib/ic/doc/html/java
+/lib/ic/java_src/SKIP
# jinterface
@@ -231,15 +243,23 @@ a.out.dSYM/
/system/doc/pdf/*.pdf
/system/doc/pdf/*.fo
+/system/doc/html/*.html
+/system/doc/html/*.eix
+/system/doc/html/js
/system/doc/html/*/*.html
/system/doc/html/*/*.gif
/system/doc/html/*/*.eix
+/system/doc/top/PR.template
+/system/doc/top/erlresolvelinks.js
/system/doc/programming_examples/funs.xml
/system/doc/tutorial/c_port.xml
/system/doc/tutorial/c_portdriver.xml
/system/doc/tutorial/cnode.xml
/system/doc/tutorial/erl_interface.xml
/system/doc/tutorial/example.xml
+/system/doc/installation_guide/INSTALL.xml
+/system/doc/installation_guide/INSTALL-CROSS.xml
+/system/doc/installation_guide/INSTALL-WIN32.xml
# test_server
diff --git a/INSTALL-WIN32.md b/INSTALL-WIN32.md
index f59a8ece67..643cd33c84 100644
--- a/INSTALL-WIN32.md
+++ b/INSTALL-WIN32.md
@@ -1,18 +1,6 @@
How to Build Erlang/OTP on Windows
==================================
-Table of Contents
------------------
-
-1. Introduction
-2. Frequently Asked Questions
-3. Tools you Need and Their Environment
-4. The Shell Environment
-5. Building and Installing
-6. Development
-7. Final Words
-8. Copyright and License
-
Introduction
------------
@@ -27,7 +15,7 @@ sure of, but it certainly will...
The procedure described uses Cygwin as a build environment, you run
the bash shell in Cygwin and uses gnu make/configure/autoconf etc to
do the build. The emulator C-source code is, however, mostly compiled
-with Microsoft Visual C++(tm), producing a native Windows binary. This
+with Microsoft Visual C++â„¢, producing a native Windows binary. This
is the same procedure as we use to build the pre-built binaries. The
fact that we use VC++ and not gcc is explained further in the FAQ
section.
@@ -67,7 +55,7 @@ needed at all. Now we've used this build procedure for a couple of
releases, and it has worked fine for us. Still, there might be all
sorts of troubles on different machines and with different
setups. I'll try to give hints wherever I've encountered difficulties,
-but please share your experiences by using the [`erlang-questions`] [1]
+but please share your experiences by using the [erlang-questions] [1]
mailing list. I cannot of course help everyone with all
their problems, please try to solve the problems and submit
solutions/workarounds. Remember, it's all about sharing, not about
@@ -87,7 +75,7 @@ Frequently Asked Questions
from within the Cygwin environment. All other tools needed to build
Erlang are free-ware/open source, but not the C compiler.
-* Q: Why haven't you got rid of VC++ then, you `******`?
+* Q: Why haven't you got rid of VC++ then, you \*\*\*\*\*\*?
A: Well, partly because it's a good compiler - really! Actually it's
been possible in late R11-releases to build using mingw instead of
@@ -115,7 +103,7 @@ Frequently Asked Questions
emulation in Cygwin, which, I'm sure of, will improve, but still has
some problems. Fixing those problems might be easy or might be hard.
I suggest you try yourself and share your experience. No one would be
- happier if a simple ./configure && make would produce a fully fledged
+ happier if a simple `./configure && make` would produce a fully fledged
Cygwin binary. Ericsson does however not pay me to do a Cygwin port, so
such a port would have to happen in spare time, which is a limited
resource...
@@ -256,9 +244,9 @@ Frequently Asked Questions
$ ./otp_build boot -a
$ ./otp_build release -a
$ ./otp_build installer_win32
- $ release/win32/otp_win32_<OTP version> /S
+ $ release/win32/otp_win32_%OTP-REL% /S
- Voila! `Start->Programs->Erlang OTP <OTP version>->Erlang` starts the Erlang
+ Voila! `Start->Programs->Erlang OTP %OTP-REL%->Erlang` starts the Erlang
Windows shell.
@@ -431,7 +419,7 @@ Well' here's the list:
archives (`.a`, not `.lib`).
* Building with wxWidgets. Download wxWidgets-2.8.9 or higher patch
- release (2.9.* is a developer release which currently does not work
+ release (2.9.\* is a developer release which currently does not work
with wxErlang).
Install or unpack it to `DRIVE:/PATH/cygwin/opt/local/pgm`
@@ -448,13 +436,13 @@ Well' here's the list:
* The Erlang source distribution (from <http://www.erlang.org/download.html>).
The same as for Unix platforms. Preferably use tar from within Cygwin to
- unpack the source tar.gz (`tar zxf otp_src_R13B04.tar.gz`).
+ unpack the source tar.gz (`tar zxf otp_src_%OTP-REL%.tar.gz`).
- set the environment ERL_TOP to point to the root directory of the
+ set the environment `ERL_TOP` to point to the root directory of the
source distribution. Let's say I stood in `$HOME/src` and unpacked
- `otp_src_R13B04.tar.gz`, I then add the following to `.profile`:
+ `otp_src_%OTP-REL%.tar.gz`, I then add the following to `.profile`:
- ERL_TOP=$HOME/src/otp_src_R13B04
+ ERL_TOP=$HOME/src/otp_src_%OTP-REL%
export $ERL_TOP
* The TCL/TK binaries. You could compile Tcl/Tk for windows yourself,
@@ -546,94 +534,94 @@ Now you will have a file called `otp_win32_R12B.exe` in the
Lets get into more detail:
-`$ ./otp_build autoconf` - This step rebuilds the configure scripts to
-work correctly in the cygwin environment. In an ideal world, this
-would not be needed, but alas, we have encountered several
-incompatibilities between our distributed configure scripts (generated
-on a Linux platform) and the cygwin environment over the
-years. Running autoconf on cygwin ensures that the configure scripts
-are generated in a cygwin-compatible way and that they will work well
-in the next step.
-
-`$ ./otp_build configure` - This runs the newly generated configure scripts
-with options making configure behave nicely. The target machine type is
-plainly `win32`, so a lot of the configure-scripts recognize this
-awkward target name and behave accordingly. The CC variable also makes
-the compiler be cc.sh, which wraps MSVC++, so all configure tests
-regarding the C compiler gets to run the right compiler. A lot of the
-tests are not needed on Windows, but I thought it best to run the
-whole configure anyway. The only configure option you might want to
-supply is `--with-ssl`, which might be needed if you have built your own
-openssl distribution. The Shining Lights distribution should be found
-automatically by configure, if that fails, add a `--with-ssl=<dir>` that
-specifies the root directory of your OpenSSL installation.
-
-`$ ./otp_build boot -a` - This uses the bootstrap directory (shipped
-with the source, `$ERL_TOP/bootstrap`) to build a complete OTP
-system. It first builds an emulator and sets up a minimal OTP system
-under `$ERL_TOP/bootstrap`, then starts to compile the different OTP
-compilers to make the `$ERL_TOP/bootstrap` system potent enough to be
-able to compile all Erlang code in OTP. Then, all Erlang and C code
-under `$ERL_TOP/lib` is built using the bootstrap system, giving a
-complete OTP system (although not installed). When this is done, one
-can run Erlang from within the source tree, just type `$ERL_TOP/bin/erl`
-and you should have a prompt. If you omit the -a flag, you'll get a
-smaller system, that might be useful during development. Now
-exit from Erlang and start making a release of the thing:
-
-`$ ./otp_build release -a` - Builds a commercial release tree from the
-source tree, default is to put it in `$ERL_TOP/release/win32`, you can
-give any directory as parameter (Cygwin style), but it doesn't really matter
-if you're going to build a self extracting installer too. You could of
-course build release to the final directory and then run `./Install.exe`
-standing in the directory where the release was put, that will create
-a fully functional OTP installation. But let's make the nifty
-installer:
-
-`$ ./otp_build installer_win32` - Create the self extracting installer
-executable. The executable `otp_win32_<OTP version>.exe` will be placed
-in the top directory of the release created in the previous step. If
-no release directory is specified, the release is expected to have
-been built to `$ERL_TOP/release/win32`, which also will be the place
-where the installer executable will be placed. If you specified some
-other directory for the release (i.e.
-`./otp_build release -a /tmp/erl_release`), you're expected to give the
-same parameter here, (i.e. `./otp_build installer_win32 /tmp/erl_release`).
-You need to have a full NSIS installation and `makensis.exe` in your
-path for this to work of course. Once you have created the installer,
-you can run it to install Erlang/OTP in the regular way, just run the
-executable and follow the steps in the installation wizard. To get all
-default settings in the installation without any questions asked, you
-run the executable with the parameter `/S` (capital S). like in:
-
- $ cd $ERL_TOP
- $ release/win32/otp_win32_R13B04 /S
- ...
-
-and after a while Erlang will have been installed in
-`C:\Program Files\erl5.7.5`, with shortcuts in the menu etc.
-
-*NOTE* Beginning with R9C, the Windows installer does *not* add Erlang
-to the system wide path. If one wants to have Erlang in the path, one
-has to add it by hand.
-
-The necessary setup of an Erlang installation is actually done by the
-program `Install.exe`, which resides in the release top. That program
-creates `.ini`-files and copies the correct boot scripts. If one has
-the correct directory tree (like after a `./otp_build release -a`), only
-the running of Install.exe is necessary to get a fully functional
-OTP. What the self extracting installer adds is (of course) the
-possibility to distribute the binary easily, together with adding
-shortcuts to the Windows start menu. There is also some adding of
-entries in the registry, to associate `.erl` and `.beam` files with Erlang
-and get nifty icons, but that's not something you'll really need to
-run Erlang. The registry is also used to store uninstall information,
-but if one has not used the self extracting installer, one cannot
-(need not) do any uninstall, one just scratches the release directory
-and everything is gone. Erlang/OTP does not *need* to put anything
-in the Windows registry at all, and does not if you don't use the self
-extracting installer. In other words the installer is pure cosmetics.
-
+1. `$ ./otp_build autoconf` - This step rebuilds the configure scripts
+ to work correctly in the cygwin environment. In an ideal world, this
+ would not be needed, but alas, we have encountered several
+ incompatibilities between our distributed configure scripts (generated
+ on a Linux platform) and the cygwin environment over the
+ years. Running autoconf on cygwin ensures that the configure scripts
+ are generated in a cygwin-compatible way and that they will work well
+ in the next step.
+
+2. `$ ./otp_build configure` - This runs the newly generated configure
+ scripts with options making configure behave nicely. The target machine
+ type is plainly `win32`, so a lot of the configure-scripts recognize
+ this awkward target name and behave accordingly. The CC variable also
+ makes the compiler be `cc.sh`, which wraps MSVC++, so all configure
+ tests regarding the C compiler gets to run the right compiler. A lot of
+ the tests are not needed on Windows, but I thought it best to run the
+ whole configure anyway. The only configure option you might want to
+ supply is `--with-ssl`, which might be needed if you have built your
+ own OpenSSL distribution. The Shining Lights distribution should be
+ found automatically by `configure`, if that fails, add a
+ `--with-ssl=<dir>` that specifies the root directory of your OpenSSL
+ installation.
+
+3. `$ ./otp_build boot -a` - This uses the bootstrap directory (shipped
+ with the source, `$ERL_TOP/bootstrap`) to build a complete OTP
+ system. It first builds an emulator and sets up a minimal OTP system
+ under `$ERL_TOP/bootstrap`, then starts to compile the different OTP
+ compilers to make the `$ERL_TOP/bootstrap` system potent enough to be
+ able to compile all Erlang code in OTP. Then, all Erlang and C code
+ under `$ERL_TOP/lib` is built using the bootstrap system, giving a
+ complete OTP system (although not installed). When this is done, one
+ can run Erlang from within the source tree, just type `$ERL_TOP/bin/erl`
+ and you should have a prompt. If you omit the -a flag, you'll get a
+ smaller system, that might be useful during development. Now
+ exit from Erlang and start making a release of the thing:
+
+4. `$ ./otp_build release -a` - Builds a commercial release tree from the
+ source tree, default is to put it in `$ERL_TOP/release/win32`, you can
+ give any directory as parameter (Cygwin style), but it doesn't really
+ matter if you're going to build a self extracting installer too. You
+ could of course build release to the final directory and then run
+ `./Install.exe` standing in the directory where the release was put,
+ that will create a fully functional OTP installation. But let's make
+ the nifty installer:
+
+5. `$ ./otp_build installer_win32` - Create the self extracting installer
+ executable. The executable `otp_win32_%OTP-REL%.exe` will be placed
+ in the top directory of the release created in the previous step. If
+ no release directory is specified, the release is expected to have
+ been built to `$ERL_TOP/release/win32`, which also will be the place
+ where the installer executable will be placed. If you specified some
+ other directory for the release (i.e. `./otp_build release -a
+ /tmp/erl_release`), you're expected to give the same parameter here,
+ (i.e. `./otp_build installer_win32 /tmp/erl_release`). You need to have
+ a full NSIS installation and `makensis.exe` in your path for this to
+ work of course. Once you have created the installer, you can run it to
+ install Erlang/OTP in the regular way, just run the executable and
+ follow the steps in the installation wizard. To get all default settings
+ in the installation without any questions asked, you run the executable
+ with the parameter `/S` (capital S) like in:
+
+ $ cd $ERL_TOP
+ $ release/win32/otp_win32_%OTP-REL% /S
+ ...
+
+ and after a while Erlang/OTP-%OTP-REL% will have been installed in
+ `C:\Program Files\erl%ERTS-VSN%\`, with shortcuts in the menu etc.
+
+ The necessary setup of an Erlang installation is actually done by the
+ program `Install.exe`, which resides in the release top. That program
+ creates `.ini`-files and copies the correct boot scripts. If one has
+ the correct directory tree (like after a `./otp_build release -a`), only
+ the running of `Install.exe` is necessary to get a fully functional
+ OTP. What the self extracting installer adds is (of course) the
+ possibility to distribute the binary easily, together with adding
+ shortcuts to the Windows start menu. There is also some adding of
+ entries in the registry, to associate `.erl` and `.beam` files with
+ Erlang and get nifty icons, but that's not something you'll really need
+ to run Erlang. The registry is also used to store uninstall information,
+ but if one has not used the self extracting installer, one cannot
+ (need not) do any uninstall, one just scratches the release directory
+ and everything is gone. Erlang/OTP does not *need* to put anything
+ in the Windows registry at all, and does not if you don't use the self
+ extracting installer. In other words the installer is pure cosmetics.
+
+> *NOTE*: Beginning with R9C, the Windows installer does *not* add Erlang
+> to the system wide path. If one wants to have Erlang in the path, one
+> has to add it by hand.
Development
-----------
@@ -694,7 +682,7 @@ or even in the source directory...
$ make opt
Note that you're expected o have a fresh Erlang in your path when
-doing this, preferably the plain R13B04 you have built in the previous
+doing this, preferably the plain %OTP-REL% you have built in the previous
steps. You could also add `$ERL_TOP/bootstrap/bin` to your `PATH` before
rebuilding specific libraries, that would give you a good enough
Erlang system to compile any OTP erlang code. Setting up the path
@@ -704,7 +692,8 @@ correctly is a little bit tricky, you still need to have
in the path. A typical setting of the path for using the bootstrap
compiler would be:
- $ export PATH=$ERL_TOP/erts/etc/win32/cygwin_tools/vc:$ERL_TOP/erts/etc/win32/cygwin_tools:$ERL_TOP/bootstrap/bin:$PATH
+ $ export PATH=$ERL_TOP/erts/etc/win32/cygwin_tools/vc\
+ :$ERL_TOP/erts/etc/win32/cygwin_tools:$ERL_TOP/bootstrap/bin:$PATH
That should make it possible to rebuild any library without hassle...
@@ -760,22 +749,31 @@ Patrik, OTP
Copyright and License
---------------------
-> %CopyrightBegin%
->
-> Copyright Ericsson AB 2003-2010. All Rights Reserved.
->
-> The contents of this file are subject to the Erlang Public License,
-> Version 1.1, (the "License"); you may not use this file except in
-> compliance with the License. You should have received a copy of the
-> Erlang Public License along with this software. If not, it can be
-> retrieved online at http://www.erlang.org/.
->
-> Software distributed under the License is distributed on an "AS IS"
-> basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-> the License for the specific language governing rights and limitations
-> under the License.
->
-> %CopyrightEnd%
+%CopyrightBegin%
+
+Copyright Ericsson AB 2003-2010. All Rights Reserved.
+
+The contents of this file are subject to the Erlang Public License,
+Version 1.1, (the "License"); you may not use this file except in
+compliance with the License. You should have received a copy of the
+Erlang Public License along with this software. If not, it can be
+retrieved online at http://www.erlang.org/.
+
+Software distributed under the License is distributed on an "AS IS"
+basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+the License for the specific language governing rights and limitations
+under the License.
+
+%CopyrightEnd%
+
+Modifying This Document
+-----------------------
+
+Before modifying this document you need to have a look at the
+`$ERL_TOP/README.md.txt` document.
+
[1]: http://www.erlang.org/faq.html "mailing lists"
+
+ [?TOC]: true
diff --git a/INSTALL.md b/INSTALL.md
index 452b0ff252..b26c0ce018 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -1,8 +1,12 @@
Building and Installing Erlang/OTP
==================================
-Please read the whole file before attempting to build and install Erlang/OTP.
-You can find more information about Open Source Erlang/OTP at:
+Introduction
+------------
+
+This document describes how to build and install Erlang/OTP-%OTP-REL%. You
+are advised to read the whole document before attempting to build and install
+Erlang/OTP. You can find more information about Open Source Erlang/OTP at:
<http://www.erlang.org/>
@@ -10,24 +14,22 @@ The source code for Erlang/OTP can also be found in a Git repository:
<http://github.com/erlang/otp>
-Portability
------------
-
Erlang/OTP should be possible to build from source on any Unix system,
including Mac OS X. This document describes how to native compile Erlang/OTP
on Unix. For detailed instructions on how to
-* cross compile Erlang/OTP, see the [`$ERL_TOP/INSTALL-CROSS.md`] [1]
+* cross compile Erlang/OTP, see the [$ERL_TOP/INSTALL-CROSS.md][]
document.
-* build Erlang/OTP on Windows, see the [`$ERL_TOP/INSTALL-WIN32.md`] [2]
+* build Erlang/OTP on Windows, see the [$ERL_TOP/INSTALL-WIN32.md][]
document.
Binary releases for Windows can be found at
<http://www.erlang.org/download.html>.
-However, you are in any case advised to read this document first, since it
-covers building Erlang/OTP in general as well as other important information.
+Before reading the above mensioned documents you are in any case advised to
+read this document first, since it covers building Erlang/OTP in general as
+well as other important information.
Daily Build and Test
--------------------
@@ -44,9 +46,9 @@ At Ericsson we have a "Daily Build and Test" that runs on:
* x86
* SuSE Linux/GNU 10.0, 10.1
* x86
- * x86_64
+ * x86\_64
* SuSE Linux/GNU 11.0
- * x86_64
+ * x86\_64
* Gentoo Linux/GNU 1.12.11.1
* x86
* MontaVista Linux/GNU 4.0.1
@@ -60,15 +62,15 @@ At Ericsson we have a "Daily Build and Test" that runs on:
We also have the following "Daily Cross Builds":
-* SuSE Linux/GNU 10.1 x86 -> SuSE Linux/GNU 10.1 x86_64
-* SuSE Linux/GNU 10.1 x86_64 -> Linux/GNU TILEPro64
+* SuSE Linux/GNU 10.1 x86 -> SuSE Linux/GNU 10.1 x86\_64
+* SuSE Linux/GNU 10.1 x86\_64 -> Linux/GNU TILEPro64
and the following "Daily Cross Build Tests":
-* SuSE Linux/GNU 10.1 x86_64
+* SuSE Linux/GNU 10.1 x86\_64
-Versions Known *not* to Work
-----------------------------
+Versions Known NOT to Work
+--------------------------
* Suse linux 9.1 is shipped with a patched GCC version 3.3.3, having the
rpm named `gcc-3.3.3-41`. That version has a serious optimization bug
@@ -118,14 +120,15 @@ These are the tools you will need in order to unpack and build Erlang/OTP.
### Building ###
-* GNU make
-* GNU C compiler
+* GNU `make`
+* `gcc` -- GNU C compiler
* Perl 5
-* GNU m4 -- If hipe (native code) support is enabled.
-* ncurses (or termcap or termlib) -- The development headers and libraries
- are needed, often known as ncurses-devel. (Use --without-termcap to build
- without any of these libraries. Only the old shell (without any line
- editing) can be used.)
+* GNU `m4` -- If HiPE (native code) support is enabled. HiPE can be
+ disabled using `--disable-hipe`
+* `ncurses`, `termcap`, or `termlib` -- The development headers and
+ libraries are needed, often known as `ncurses-devel`. Use
+ `--without-termcap` to build without any of these libraries. Note that
+ in this case only the old shell (without any line editing) can be used.
* OpenSSL -- Optional, but needed for building the Erlang/OTP applications
`ssl` and `crypto`. You need the "development package" of OpenSSL, i.e.
including the header files. For building the application `ssl` the OpenSSL
@@ -140,23 +143,21 @@ These are the tools you will need in order to unpack and build Erlang/OTP.
* `sed` -- There seem to be some problems with some of the `sed` version on
Solaris. Make sure `/bin/sed` or `/usr/bin/sed` is used on the Solaris
platform.
-* Flex -- Optional, headers and libraries are needed to build the flex
+* `flex` -- Optional, headers and libraries are needed to build the `flex`
scanner for the `megaco` application on Unix/Linux.
-If you are building in a Git working directory you also have to have a GNU
-`autoconf` of at least version 2.59. Autoconf is however not needed if you
-build an unmodified version of the released source.
-
#### Building Documentation ####
* `xsltproc` -- XSLT processor. A tool for applying XSLT stylesheets
to XML documents. Can be downloaded from
<http://xmlsoft.org/XSLT/xsltproc2.html>.
-* `fop` -- Apache FOP print formatter (requires Java). Can be downloaded from
- <http://xmlgraphics.apache.org/fop>.
-* `Markdown.pl` -- Optional. This is a `perl` script that generates an
- HTML version of a document written in Markdown notation. Can be
- downloaded at <http://daringfireball.net/projects/markdown>.
+* `fop` -- Apache FOP print formatter (requires Java). Can be downloaded
+ from <http://xmlgraphics.apache.org/fop>.
+
+#### Building in Git ####
+
+* GNU `autoconf` of at least version 2.59. Note that `autoconf` is not
+ needed when building an unmodified version of the released source.
### Installing ###
@@ -165,12 +166,12 @@ build an unmodified version of the released source.
How to Build and Install Erlang/OTP
-----------------------------------
-The following instructions are for building using the source tar ball.
+The following instructions are for building [the released source tar ball][].
The variable `$ERL_TOP` will be mentioned a lot of times. It refers to
the top directory in the source tree. More information about `$ERL_TOP`
-can be found in the "`make` and `$ERL_TOP`" section below. If you are
-building in git you probably want to take a look at the "Building in Git"
+can be found in the [make and $ERL_TOP][] section below. If you are
+building in git you probably want to take a look at the [Building in Git][]
section below before proceeding.
### Unpacking ###
@@ -178,13 +179,16 @@ section below before proceeding.
Step 1: Start by unpacking the Erlang/OTP distribution file with your GNU
compatible TAR program.
- $ gunzip -c otp_src_R13B04.tar.gz | tar xf -
- $ zcat otp_src_R13B04.tar.gz | tar xf -
+ $ gunzip -c otp_src_%OTP-REL%.tar.gz | tar xf -
+
+alternatively:
+
+ $ zcat otp_src_%OTP-REL%.tar.gz | tar xf -
Step 2: Now cd into the base directory (`$ERL_TOP`).
- $ cd otp_src_R13B04
+ $ cd otp_src_%OTP-REL%
### Configuring ###
@@ -208,8 +212,8 @@ To instead install in `<BaseDir>/{bin,lib/erlang}`, use the
`--prefix=<BaseDir>` option.
If you upgraded the source with some patch you may need to clean up
-from previous builds before the new build. Do a `make clean`; see
-"Caveats" below.
+from previous builds before the new build. Before doing a `make clean`,
+be sure to read the [Pre-built Source Release][] section below.
### Building ###
@@ -237,46 +241,54 @@ type `./configure --help` or `./configure --help=recursive` for details.
`./configure --help=recursive` will give help for all `configure` scripts in
all applications.
-One of the things you can specify is where Erlang/OTP should be installed: by
-default Erlang/OTP will be installed in `/usr/local/{bin,lib/erlang}`;
-to keep the same structure but install in a different place, `<Dir>` say,
+One of the things you can specify is where Erlang/OTP should be installed. By
+default Erlang/OTP will be installed in `/usr/local/{bin,lib/erlang}`.
+To keep the same structure but install in a different place, `<Dir>` say,
use the `--prefix` argument like this: `./configure --prefix=<Dir>`.
Some of the available `configure` options are:
- * `--prefix=PATH`: Specify installation prefix.
- * `--{enable,disable}-threads`: Thread support (enabled by default if
+* `--prefix=PATH` - Specify installation prefix.
+* `--{enable,disable}-threads` - Thread support (enabled by default if
possible)
- * `--{enable,disable}-smp-support`: SMP support (enabled by default if
+* `--{enable,disable}-smp-support` - SMP support (enabled by default if
possible)
- * `--{enable,disable}-kernel-poll`: Kernel poll support (enabled by default
- if possible)
- * `--{enable,disable}-hipe`: HiPE support (enabled by default on supported
+* `--{enable,disable}-kernel-poll` - Kernel poll support (enabled by
+ default if possible)
+* `--{enable,disable}-hipe` - HiPE support (enabled by default on supported
platforms)
- * `--enable-darwin-universal`: Build universal binaries on darwin i386.
- * `--enable-darwin-64bit`: Build 64bit binaries on darwin
- * `--enable-m64-build`: Build 64bit binaries using the -m64 flag to (g)cc
- * `--enable-m32-build`: Build 32bit binaries using the -m32 flag to (g)cc
- * `--{with,without}-termcap`: termcap (without implies that only the old
+* `--enable-darwin-universal` - Build universal binaries on darwin i386.
+* `--enable-darwin-64bit` - Build 64-bit binaries on darwin
+* `--enable-m64-build` - Build 64-bit binaries using the `-m64` flag to
+ `(g)cc`
+* `--enable-m32-build` - Build 32-bit binaries using the `-m32` flag to
+ `(g)cc`
+* `--{with,without}-termcap` - termcap (without implies that only the old
Erlang shell can be used)
- * `--with-javac=JAVAC`: Specify Java compiler to use
- * `--{with,without}-javac`: Java compiler (without implies that the
- `jinterface` application won't be built).
- * `--{enable,disable}-dynamic-ssl-lib`: Dynamic OpenSSL libraries
- * `--{enable,disable}-shared-zlib`: Shared zlib library
- * `--with-ssl=PATH`: Specify location of OpenSSL include and lib
- * `--{with,without}-ssl`: OpenSSL (without implies that the `crypto`, `ssh`,
- and `ssl` won't be built)
-
-If you or your system has special requirements please read the
-Makefile for additional configuration information.
+* `--with-javac=JAVAC` - Specify Java compiler to use
+* `--{with,without}-javac` - Java compiler (without implies that the
+ `jinterface` application won't be built)
+* `--{enable,disable}-dynamic-ssl-lib` - Dynamic OpenSSL libraries
+* `--{enable,disable}-shared-zlib` - Shared zlib library
+* `--with-ssl=PATH` - Specify location of OpenSSL include and lib
+* `--{with,without}-ssl` - OpenSSL (without implies that the `crypto`,
+ `ssh`, and `ssl` won't be built)
+
+If you or your system has special requirements please read the `Makefile` for
+additional configuration information.
#### Building ####
Step 5 builds the Erlang/OTP system. On a fast computer, this will take about
5 minutes. After completion of this step, you should have a working
Erlang/OTP system which you can try by typing `bin/erl`. This should start
-up Erlang/OTP and give you a prompt.
+up Erlang/OTP and give you a prompt:
+
+ $ bin/erl
+ Erlang %OTP-REL% (erts-%ERTS-VSN%) [source] [smp:4:4] [rq:4] [async-threads:0] [kernel-poll:false]
+
+ Eshell V%ERTS-VSN% (abort with ^G)
+ 1> _
#### Installing ####
@@ -286,7 +298,7 @@ without having to do step 5 again).
##### Alternative Installation Procedures #####
-* Staged install using [`DESTDIR`] [3]. You can perform the install
+* Staged install using [DESTDIR][]. You can perform the install
phase in a temporary directory and later move the installation into
its correct location by use of the `DESTDIR` variable:
@@ -366,7 +378,7 @@ without having to do step 5 again).
if you want to try the system out, running test suites, etc, before doing
the real install without `EXTRA_PREFIX`.
-### Symbolic Links in `--bindir` ###
+### Symbolic Links in --bindir ###
When doing `make install` and the default installation prefix is used,
relative symbolic links will be created from `/usr/local/bin` to all public
@@ -380,6 +392,24 @@ passed to `configure`. One can force relative, or absolute links by passing
phase. Note that such a request might cause a failure if the request cannot
be satisfied.
+### Pre-built Source Release ###
+
+The source release is delivered with a lot of platform independent
+build results already pre-built. If you want to remove these pre-built
+files, invoke `./otp_build remove_prebuilt_files` from the `$ERL_TOP`
+directory. After you have done this, you can build exactly the same way
+as before, but the build process will take a much longer time.
+
+> *WARNING*: Doing `make clean` in an arbitrary directory of the source
+> tree, may remove files needed for bootstrapping the build.
+>
+> Doing `./otp_build save_bootstrap` from the `$ERL_TOP` directory before
+> doing `make clean` will ensure that it will be possible to build after
+> doing `make clean`. `./otp_build save_bootstrap` will be invoked
+> automatically when `make` is invoked from `$ERL_TOP` with either the
+> `clean` target, or the default target. It is also automatically invoked
+> if `./otp_build remove_prebuilt_files` is invoked.
+
### Building in Git ###
When building in a Git working directory you also have to have a GNU `autoconf`
@@ -394,32 +424,13 @@ content, and you may therefore have to regenerate the `configure` scripts
when checking out a branch. Regenerated `configure` scripts imply that you
have to run `configure` and build again.
-Note that running `./otp_build autoconf` is **not** needed when building an
-unmodified version the released source.
+> *NOTE*: Running `./otp_build autoconf` is **not** needed when building
+> an unmodified version the released source.
Other useful information can be found at our github wiki:
<http://wiki.github.com/erlang/otp>
-Pre-built Source Tree
----------------------
-
-The source tree is delivered with a lot of platform independent
-build results already pre-built. If you want to remove these pre-built
-files, invoke `./otp_build remove_prebuilt_files` from the `$ERL_TOP`
-directory. After you have done this, you can build exactly the same way
-as before, but the build process will take a much longer time.
-
-*NOTE*: Doing `make clean` in an arbitrary directory of the source tree,
-may remove files needed for bootstrapping the build. Doing
-`./otp_build save_bootstrap` from the `$ERL_TOP` directory before
-doing `make clean` will ensure that it will be possible to build after
-doing `make clean`. `./otp_build save_bootstrap` will be invoked
-automatically when `make` is invoked from `$ERL_TOP` with either the
-`clean` target, or the default target. It is also automatically invoked
-if `./otp_build remove_prebuilt_files` is invoked.
-
-`make` and `$ERL_TOP`
----------------------
+### make and $ERL\_TOP ###
All the makefiles in the entire directory tree use the environment
variable `ERL_TOP` to find the absolute path of the installation. The
@@ -437,8 +448,10 @@ want to rebuild the application `STDLIB`, then you could do:
where `<Dir>` would be what you find `ERL_TOP` is set to in the top level
Makefile.
-How to Build the Erlang/OTP Documentation
------------------------------------------
+The Erlang/OTP Documentation
+----------------------------
+
+### How to Build the Documentation ###
$ cd $ERL_TOP
@@ -448,19 +461,10 @@ already ran `configure` and do not need to do this again; otherwise, run
$ ./configure [Configure Args]
-When building the documentation you need a full Erlang/OTP-R13B04 system in
+When building the documentation you need a full Erlang/OTP-%OTP-REL% system in
the `$PATH`.
- $ export PATH=<Erlang/OTP-R13B04 bin dir>:$PATH # Assuming bash/sh
-
-This document as well as some other documents have been written using
-Markdown notation. HTML versions of these documents are created and included
-in the HTML documentation if the environment variable `MD2HTML` is set to a
-command that generates HTML on `stdout` for a Markdown document passed as
-argument. This is a last minute hack, which will be handled in a better way
-in the future. We currently set `MD2HTML` as follows.
-
- $ export MD2HTML="perl <path to script>/Markdown.pl --html4tags"
+ $ export PATH=<Erlang/OTP-%OTP-REL% bin dir>:$PATH # Assuming bash/sh
Build the documentation.
@@ -478,13 +482,13 @@ or using the `release_docs` target.
* If you have installed Erlang/OTP using the `release` target, install
the documentation using the `release_docs` target. You typically want
- to use the same RELEASE_ROOT as when invoking `make release`.
+ to use the same `RELEASE_ROOT` as when invoking `make release`.
$ make release_docs RELEASE_ROOT=<release dir>
-### Build Issues ###
+#### Build Issues ####
-We have sometimes experienced problems with suns `java` running out of
+We have sometimes experienced problems with Sun's `java` running out of
memory when running `fop`. Increasing the amount of memory available
as follows has in our case solved the problem.
@@ -493,23 +497,22 @@ as follows has in our case solved the problem.
More information can be found at
<http://xmlgraphics.apache.org/fop/0.95/running.html#memory>.
-How to Install the Pre-formatted Erlang/OTP Documentation
----------------------------------------------------------
+### How to Install the Pre-formatted Documentation ###
-Pre-formatted documentation can be downloaded at
+Pre-formatted [html documentation][] and [man pages][] can be downloaded at
<http://www.erlang.org/download.html>.
For some graphical tools to find the on-line help you have to install
the HTML documentation on top of the installed OTP applications, i.e.
$ cd <ReleaseDir>
- $ gunzip -c otp_html_R13B04.tar.gz | tar xf -
+ $ gunzip -c otp_html_%OTP-REL%.tar.gz | tar xf -
For `erl -man <page>` to work the Unix manual pages have to be
installed in the same way, i.e.
$ cd <ReleaseDir>
- $ gunzip -c otp_man_R13B04.tar.gz | tar xf -
+ $ gunzip -c otp_man_%OTP-REL%.tar.gz | tar xf -
Where `<ReleaseDir>` is
@@ -620,7 +623,7 @@ To add hipe options, write like this from the Erlang shell:
1> c(Module, [native,{hipe,HipeOptions}|MoreOptions]).
-Use hipe:help_options/0 to print out the available options.
+Use `hipe:help_options/0` to print out the available options.
1> hipe:help_options().
@@ -702,6 +705,7 @@ purposes.
Authors
-------
+
Authors are mostly listed in the application's `AUTHORS` files,
that is `$ERL_TOP/lib/*/AUTHORS` and `$ERL_TOP/erts/AUTHORS`,
not in the individual source files.
@@ -709,30 +713,44 @@ not in the individual source files.
Copyright and License
---------------------
-> %CopyrightBegin%
->
-> Copyright Ericsson AB 1998-2010. All Rights Reserved.
->
-> The contents of this file are subject to the Erlang Public License,
-> Version 1.1, (the "License"); you may not use this file except in
-> compliance with the License. You should have received a copy of the
-> Erlang Public License along with this software. If not, it can be
-> retrieved online at http://www.erlang.org/.
->
-> Software distributed under the License is distributed on an "AS IS"
-> basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-> the License for the specific language governing rights and limitations
-> under the License.
->
-> %CopyrightEnd%
+%CopyrightBegin%
+
+Copyright Ericsson AB 1998-2010. All Rights Reserved.
+
+The contents of this file are subject to the Erlang Public License,
+Version 1.1, (the "License"); you may not use this file except in
+compliance with the License. You should have received a copy of the
+Erlang Public License along with this software. If not, it can be
+retrieved online at http://www.erlang.org/.
+
+Software distributed under the License is distributed on an "AS IS"
+basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+the License for the specific language governing rights and limitations
+under the License.
+
+%CopyrightEnd%
More Information
----------------
More information can be found at <http://www.erlang.org>.
+Modifying This Document
+-----------------------
+
+Before modifying this document you need to have a look at the
+`$ERL_TOP/README.md.txt` document.
+
+
+ [$ERL_TOP/INSTALL-CROSS.md]: INSTALL-CROSS
+ [$ERL_TOP/INSTALL-WIN32.md]: INSTALL-WIN32
+ [DESTDIR]: http://www.gnu.org/prep/standards/html_node/DESTDIR.html
+ [Building in Git]: #How-to-Build-and-Install-ErlangOTP_Building-in-Git
+ [Pre-built Source Release]: #How-to-Build-and-Install-ErlangOTP_Prebuilt-Source-Release
+ [make and $ERL_TOP]: #How-to-Build-and-Install-ErlangOTP_make-and-ERLTOP
+ [html documentation]: http://www.erlang.org/download/otp_doc_html_%OTP-REL%.tar.gz
+ [man pages]: http://www.erlang.org/download/otp_doc_man_%OTP-REL%.tar.gz
+ [the released source tar ball]: http://www.erlang.org/download/otp_src_%OTP-REL%.tar.gz
- [1]: INSTALL-CROSS.html "$ERL_TOP/INSTALL-CROSS.md"
- [2]: INSTALL-WIN32.html "$ERL_TOP/INSTALL-WIN32.md"
- [3]: http://www.gnu.org/prep/standards/html_node/DESTDIR.html "DESTDIR"
+ [?TOC]: true
diff --git a/Makefile.in b/Makefile.in
index 12e485754f..30aab6add1 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -28,10 +28,10 @@ SHELL = /bin/sh
ERL_TOP = @ERL_TOP@
# OTP release
-OTP = @OTP@
+OTP = OTP-@OTP_REL@
# erts (Erlang RunTime System) version
-ERTS = @ERTS@
+ERTS = erts-@ERTS_VSN@
# ----------------------------------------------------------------------
@@ -397,7 +397,7 @@ endif
# ---------------------------------------------------------------
# Target only used when building commercial ERTS patches
# ---------------------------------------------------------------
-release_docs docs: html_readmes
+release_docs docs:
ifeq ($(OTP_SMALL_BUILD),true)
cd $(ERL_TOP)/lib && \
ERL_TOP=$(ERL_TOP) $(MAKE) TESTROOT=$(RELEASE_ROOT) $@
@@ -412,41 +412,6 @@ endif
cd $(ERL_TOP)/system/doc && \
ERL_TOP=$(ERL_TOP) $(MAKE) TESTROOT=$(RELEASE_ROOT) $@
-.PHONY: html_readmes clean_html_readmes
-
-HTML_READMES = INSTALL.html INSTALL-WIN32.html INSTALL-CROSS.html
-
-html_readmes: $(HTML_READMES)
-
-clean_html_readmes:
- rm -f $(HTML_READMES)
-
-%.html: %.md
- echo "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">" > $@
- echo "<html xmlns:fn=\"http://www.w3.org/2005/02/xpath-functions\"><head>" >> $@
- echo "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">" >> $@
- echo "<style type=\"text/css\">" >> $@
- echo "body {" >> $@
- echo " margin: 4em 4em 4em 4em;" >> $@
- echo " background: white;" >> $@
- echo " font-family: Verdana, Arial, Helvetica, sans-serif;" >> $@
- echo "}" >> $@
- echo "code { font-family: courier;font-weight: normal}" >> $@
- echo "a:link { color: blue; text-decoration: none }" >> $@
- echo "a:active { color: blue; text-decoration: none }" >> $@
- echo "a:visited { color: blue; text-decoration: none }" >> $@
- echo "</style><title>" >> $@
- cat $< | sed -n "s/[ ]*\([^ ].*[^ ]\)[ ]*/\1/p;/[ ]*[^ ][ ]*/q" >> $@
- echo "</title></head><body>" >> $@
-ifneq ($(MD2HTML),)
- $(MD2HTML) $< >> $@
-else
- echo "<pre>" >> $@
- cat $< | sed "s|\&|\&amp\;|g;s|\"|\&quot\;|g;s|<|\&lt\;|g;s|>|\&gt\;|g" >> $@
- echo "</pre>" >> $@
-endif
- echo "</body></html>" >> $@
-
# ----------------------------------------------------------------------
ERLANG_EARS=$(BOOTSTRAP_ROOT)/bootstrap/erts
ELINK=$(BOOTSTRAP_ROOT)/bootstrap/erts/bin/elink
@@ -1032,7 +997,7 @@ $(IBIN_DIR):
# Clean targets
#
-clean: check_recreate_primary_bootstrap clean_html_readmes
+clean: check_recreate_primary_bootstrap
rm -f *~ *.bak config.log config.status prebuilt.files ibin/*
find . -type f -name SKIP -print | xargs $(RM)
cd erts && ERL_TOP=$(ERL_TOP) $(MAKE) clean
diff --git a/README.md.txt b/README.md.txt
new file mode 100644
index 0000000000..a5a1bf4b7d
--- /dev/null
+++ b/README.md.txt
@@ -0,0 +1,266 @@
+Erlangish Markdown Text Files
+=============================
+
+Introduction
+------------
+
+If you are looking for information on how to build and install Erlang/OTP you
+want to read the [$ERL_TOP/INSTALL.md][] document instead of this document
+(where `$ERL_TOP` is the top source directory in the source tree).
+
+All files with the `.md` suffix (as well as this file) are ordinary text files
+written using a Markdown like notation, and can be read using an ordinary text
+editor such as for example `emacs`.
+
+This document describes how `*.md` files in the Erlang/OTP source tree should
+be written.
+
+> *NOTE*: Before modifying a `*.md` file read all of this document.
+
+Erlangish Markdown
+------------------
+
+We do not use Markdown straight out of the box. The Markdown syntax we use is
+similar to the original Markdown but with a number of tweaks. The original
+Markdown is documented at <http://daringfireball.net/projects/markdown/>. You
+should read that documentation as well as this document before modifying any
+Erlangish Markdown files in the Erlang/OTP source tree.
+
+The original Markdown syntax was designed for generating HTML code from an
+"easy to read/easy to write" plain text. Instead of generating HTML we generate
+XML that fits into our documentation, i.e. we generate Erlangish XML from
+Erlangish Markdown.
+
+The `.md` suffix has been chosen since [github][] will generate HTML pages for
+files with the `.md` suffix. Github does however not generate HTML according to
+Erlangish Markdown, so some features do not work. The Erlangish Markdown
+documents viewed at [our github repository][] will typically suffer from broken
+links. The original Markdown script, gitub's Markdown, and our Erlangish
+Markdown script will generate somewhat different results if you do not follow
+indentation rules outlined in the Markdown documentation. You are encouraged to
+try to write using a Markdown syntax that also looks nice on github. However,
+it is *much* more important that the document is formatted correct in the
+Erlang/OTP documentation.
+
+### Differences Between Markdown and Erlangish Markdown ###
+
+#### Missing Features ####
+
+This functionality is missing compared to Markdown version 1.0.1. Do not
+depend on the fact that these features are missing. Some of them might appear
+in the future.
+
+* No inline HTML. Currently no inline XML is allowed either. Inline XML might
+ be allowed in the future, but there is no real need for it since we use
+ Erlangish Markdown for "readme"s that have a main purpose of being readable
+ in plain text.
+
+* Backslash escapes all characters.
+
+* No support for "horizontal rules".
+
+* Links.
+ * No support for the "title" attribute.
+ * Automatic links does not support email addresses.
+
+* Images.
+ * No support for the "title" attribute. Specified "title" will however
+ be used as `<icaption>`.
+ * No support for the "alt" attribute.
+
+* Lists aren't supported inside block quotes.
+
+* Link and image definition names *are* case sensitive.
+
+#### Additional Features ####
+
+* Automatic anchors at each heading.
+
+* Optionally automatically generated table of contents.
+
+* Note blocks.
+
+* Warning blocks.
+
+#### Extra requirements ####
+
+* One and only one level 1 heading is allowed and required.
+
+* The level 1 heading must be the first heading in the document.
+
+* A level `X` heading must have a level `X-1` heading as parent heading.
+
+* Link and image definition names aren't allowed to begin with a
+ question mark (?) character. Names beginning with a question mark have
+ been reserved for other use.
+
+* The encoding of the file containing Erlangish Markdown should be
+ UTF-8.
+
+### Generated XML ###
+
+> *WARNING*: The `emd2exml` script will blindly generate XML code according
+> to the Erlangish Markdown in a file. Successfully generated XML does **not**
+> imply that the generated XML adheres to used DTDs. `emd2exml` does very
+> seldom fail and can easily generate XML that will cause the documentation
+> build to fail. You always have to keep in mind that the XML generated
+> should fit the chapter DTD of Erlang/OTP. Also note that even though HTML
+> generation succeeds the PDF generation might fail, etc.
+>
+> *Always build the Erlang/OTP documentation after modifying an Erlangish
+> Markdown document!*
+
+A note about how we talk about "tags" below. When we say "generate(s) `<X>`
+tags" this also imply that ending `</X>` tags will be generated at appropriate
+places. Appropriate attributes to the `X` tag will also be generated.
+
+* Inline and reference style links will either generate `<seealso>` tags
+ or `<url>` tags. If a "://" character sequence is found in the URL an
+ `<url>` tag will be generated; otherwise, a `<seealso>` tag is generated.
+
+* Automatic links will only generate `<url>` tags. This since a
+ "://" character sequence have to be present in the URL in order
+ for the link to be identified.
+
+* Inline and reference style images will generate a `<image file="...">
+ <icaption>...</icaption> </image>` sequence where the "title" will be
+ placed between `<icaption>` and `</icaption>`.
+
+* Block quotes generate `<blockquote>` tags.
+
+* If the first line of a top level block quote begins with a `> *NOTE*:`
+ character sequence, a `<note>` tag will be generated instead of a
+ `<blockquote>` tag. The note will span the entire block quote.
+
+* If the first line of a top level block quote begins with a `> *WARNING*:`
+ character sequence, a `<warning>` tag will be generated instead of a
+ `<blockquote>` tag. The warning will span the entire block quote.
+
+* Paragraphs will generate `<p>` tags.
+
+* Break line (double trailing white space) will generate `<br/>` tags.
+
+* An unordered list generates a `<list type="bulleted">` tag and `<item>`
+ tags for each item.
+
+* An ordered list generates a `<list type="ordered">` tag and `<item>` tags
+ for each item.
+
+* Code blocks will generate `<code type="none">` tags.
+
+* Code span (backticks) will generate `<c>` tags.
+
+* Emphasis (single `*` or `_`) will generate `<em>` tags.
+
+* Strong emphasis (double `*` or `_`) will generate `<b>` tags.
+
+* The level 1 heading will cause the following to be generated:
+
+ <?xml version="1.0" encoding="utf8" ?>
+ <!DOCTYPE chapter SYSTEM "chapter.dtd">
+ <chapter>
+ <header>
+ <copyright>
+ ...
+ </copyright>
+ <legalnotice>
+ ...
+ </legalnotice>
+
+ <title>...</title>
+ ...
+ <file>...</file>
+ </header>
+
+ ...
+
+ </chapter>
+
+ The content of copyright section and the legalnotice section will
+ contain information from a \%CopyrightBegin\%, \%CopyrightEnd\% block
+ if such exist (see below).
+
+* A level `X` heading where `1 < X <= 3` will cause the the following
+ to be generated:
+
+ <marker id="..."/>
+ <section>
+ <title>...</title>
+ ...
+ </section>
+
+ The marker id is automatically generated as a combination of all parent
+ headings up to and including level 2 separated by a `_` character. As in
+ `<marker heading 2>_<marker heading 3>_ ... _<current marker heading>`
+ where each "marker heading" is constructed as follows. All characters a-z
+ and A-Z are kept as they are, space and tab characters are replaced by
+ `-` characters, and all other characters are dropped.
+
+ This way it is relatively easy to make sure that all marker ids of a
+ document are unique, but there is of course no guarantee that they are.
+
+ The upside of these auto generated markers is that we wont have to clutter
+ the document with XML or something else while being able to refer into
+ the document. The downside is that if you change a level 2 heading you
+ change a lot of marker ids which may break links into a document from
+ other documents. That is, *be careful* when changing headings in an
+ existing document.
+
+* A level `X` heading where `3 < X` will cause the the following
+ to be generated:
+
+ <marker id="..."/>
+ <p><b>...</b></p>
+ ...
+
+ Current DTD:s used don't support deeper levels of sections, and we
+ therefore simulate a section this way. The marker id is generated as for
+ a true section (see above).
+
+* If a section enclosed by \%CopyrightBegin\% and \%CopyrightEnd\% is
+ encountered, it will be interpreted as an EPL copyright and license,
+ and will be used in the header section of the document. The
+ \%CopyrightBegin\% and \%CopyrightEnd\% "tags" will be removed from
+ the output.
+
+* All occurrences of \%OTP-REL% will be replaced by current release number
+ (e.g. R14A).
+
+* All occurrences of \%ERTS-VSN% will be replaced by current ERTS version
+ (e.g. 5.8).
+
+* Adding a `[?TOC]: true` line (optionally indented with three spaces)
+ anywhere in the document will cause a table of contents to be automatically
+ generated at the beginning of the generated document.
+
+* Unicode characters (encoded in UTF-8) are allowed and will be passed
+ through as is to the output file.
+
+Copyright and License
+---------------------
+
+%CopyrightBegin%
+
+Copyright Ericsson AB 2010. All Rights Reserved.
+
+The contents of this file are subject to the Erlang Public License,
+Version 1.1, (the "License"); you may not use this file except in
+compliance with the License. You should have received a copy of the
+Erlang Public License along with this software. If not, it can be
+retrieved online at http://www.erlang.org/.
+
+Software distributed under the License is distributed on an "AS IS"
+basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+the License for the specific language governing rights and limitations
+under the License.
+
+%CopyrightEnd%
+
+
+
+ [$ERL_TOP/INSTALL.md]: doc/installation_guide:INSTALL
+ [github]: http://github.com
+ [our github repository]: http://github.com/erlang/otp
+
+
+ [?TOC]: true
diff --git a/TAR.include b/TAR.include
index 27b10d6243..5146458eea 100644
--- a/TAR.include
+++ b/TAR.include
@@ -2,6 +2,7 @@ AUTHORS
EPLICENCE
Makefile.in
README.md
+README.md.txt
INSTALL.md
INSTALL-CROSS.md
INSTALL-WIN32.md
diff --git a/configure.in b/configure.in
index 21f9a640ff..9c815414da 100644
--- a/configure.in
+++ b/configure.in
@@ -182,19 +182,23 @@ AC_PROG_RANLIB
# Get erts version and otp release from erts/vsn.mk
#
AC_MSG_CHECKING([ERTS version])
-[ERTS=erts-`sed -n "s/^VSN[ ]*=[ ]*\(.*\)/\1/p" < $ERL_TOP/erts/vsn.mk`]
-AC_MSG_RESULT([$ERTS])
-AC_SUBST(ERTS)
+[ERTS_VSN=`sed -n "s/^VSN[ ]*=[ ]*\(.*\)/\1/p" < $ERL_TOP/erts/vsn.mk`]
+AC_MSG_RESULT([$ERTS_VSN])
+AC_SUBST(ERTS_VSN)
AC_MSG_CHECKING([OTP release])
-[OTP=OTP-`sed -n "s/^SYSTEM_VSN[ ]*=[ ]*\(.*\)/\1/p" < $ERL_TOP/erts/vsn.mk`]
-AC_MSG_RESULT([$OTP])
-AC_SUBST(OTP)
+[OTP_REL=`sed -n "s/^SYSTEM_VSN[ ]*=[ ]*\(.*\)/\1/p" < $ERL_TOP/erts/vsn.mk`]
+AC_MSG_RESULT([$OTP_REL])
+AC_SUBST(OTP_REL)
AC_ARG_ENABLE(threads,
[ --enable-threads enable async thread support
--disable-threads disable async thread support])
+AC_ARG_ENABLE(halfword-emulator,
+[ --enable-halfword-emulator enable halfword emulator (only for 64bit builds)
+ --disable-halfword-emulator disable halfword emulator (only for 64bit builds)])
+
AC_ARG_ENABLE(smp-support,
[ --enable-smp-support enable smp support
--disable-smp-support disable smp support])
@@ -343,7 +347,10 @@ fi
export ERL_TOP
AC_CONFIG_SUBDIRS(lib erts)
-AC_OUTPUT(Makefile)
+AC_CONFIG_FILES([Makefile])
+AC_CONFIG_FILES([make/emd2exml], [chmod +x make/emd2exml])
+
+AC_OUTPUT
pattern="lib/*/SKIP"
files=`echo $pattern`
diff --git a/erts/configure.in b/erts/configure.in
index 5fa1245b13..6823133936 100644
--- a/erts/configure.in
+++ b/erts/configure.in
@@ -123,6 +123,14 @@ AC_ARG_ENABLE(threads,
*) enable_threads=yes ;;
esac ], enable_threads=unknown)
+AC_ARG_ENABLE(halfword-emulator,
+[ --enable-halfword-emulator enable halfword emulator (only for 64bit builds)
+ --disable-halfword-emulator disable halfword emulator (only for 64bit builds)],
+[ case "$enableval" in
+ no) enable_halfword_emualtor=no ;;
+ *) enable_halfword_emulator=yes ;;
+ esac ], enable_halfword_emulator=unknown)
+
AC_ARG_ENABLE(smp-support,
[ --enable-smp-support enable smp support
--disable-smp-support disable smp support],
@@ -749,6 +757,25 @@ esac
AC_SUBST(LIBCARBON)
+dnl Check if we should/can build a halfword emulator
+
+AC_MSG_CHECKING(if we are building a halfword emulator (32bit heap on 64bit machine))
+if test "$enable_halfword_emulator" = "yes"; then
+ if test "$ARCH" = "amd64"; then
+ AC_DEFINE(HALFWORD_HEAP_EMULATOR, [1],
+ [Define if building a halfword-heap 64bit emulator])
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_ERROR(no; halfword emulator not supported on this architecture)
+ fi
+else
+ AC_MSG_RESULT([no])
+fi
+
+
+
+
+
dnl some tests below will call this if we haven't already - and autoconf
dnl can't handle those tests being done conditionally at runtime
AC_PROG_CPP
diff --git a/erts/doc/src/alt_dist.xml b/erts/doc/src/alt_dist.xml
index a929aec97f..36d83a685b 100644
--- a/erts/doc/src/alt_dist.xml
+++ b/erts/doc/src/alt_dist.xml
@@ -434,7 +434,7 @@
(13) Word received; /* Bytes received */
(14) struct uds_data *partner; /* The partner in an accept/listen pair */
(15) struct uds_data *next; /* Next structure in list */
-(16) /* The input buffer and it's data */
+(16) /* The input buffer and its data */
(17) int buffer_size; /* The allocated size of the input buffer */
(18) int buffer_pos; /* Current position in input buffer */
(19) int header_pos; /* Where the current header is in the
@@ -825,7 +825,7 @@
I/O vector itself. One can use this to allocate the binaries
for the queue "manually" in the driver, but we'll just fill
the binary array with NULL values (line 7) , which will make
- the runtime system allocate it's own buffers when we call
+ the runtime system allocate its own buffers when we call
<c><![CDATA[driver_enqv]]></c> (line 37).</p>
<p></p>
<p>The routine builds an I/O vector containing the header bytes
@@ -942,7 +942,7 @@
between invocations of Erlang nodes with the same name.</item>
</list>
<p>The control interface gets a buffer to return its value in,
- but is free to allocate it's own buffer is the provided one is
+ but is free to allocate its own buffer is the provided one is
to small. Here is the code for <c><![CDATA[uds_control]]></c>:</p>
<code type="none"><![CDATA[
( 1) static int uds_control(ErlDrvData handle, unsigned int command,
@@ -1042,7 +1042,7 @@
<c><![CDATA[net_kernel:start/1]]></c> function, which is useful as it starts
the distribution on a running system, where tracing/debugging
can be performed. The <c><![CDATA[net_kernel:start/1]]></c> routine takes a
- list as it's single argument. The lists first element should be
+ list as its single argument. The lists first element should be
the node name (without the "@hostname") as an atom, and the second (and
last) element should be one of the atoms <c><![CDATA[shortnames]]></c> or
<c><![CDATA[longnames]]></c>. In the example case <c><![CDATA[shortnames]]></c> is
diff --git a/erts/doc/src/driver.xml b/erts/doc/src/driver.xml
index 12c79aee90..006a6160de 100644
--- a/erts/doc/src/driver.xml
+++ b/erts/doc/src/driver.xml
@@ -413,7 +413,7 @@ select(Port, Query) ->
<title>Sample asynchronous driver</title>
<p>Sometimes database queries can take long time to
complete, in our <c><![CDATA[pg_sync]]></c> driver, the emulator
- halts while the driver is doing it's job. This is
+ halts while the driver is doing its job. This is
often not acceptable, since no other Erlang processes
gets a chance to do anything. To improve on our
postgres driver, we reimplement it using the asynchronous
diff --git a/erts/doc/src/erl_dist_protocol.xml b/erts/doc/src/erl_dist_protocol.xml
index 5978af178a..1fe7ac7ecd 100644
--- a/erts/doc/src/erl_dist_protocol.xml
+++ b/erts/doc/src/erl_dist_protocol.xml
@@ -206,7 +206,7 @@ By default EPMD listens on port 4369.
<section>
<title>Unregister a node from the EPMD</title>
<p>
- A node unregister itself from the EPMD by simply closing the
+ A node unregisters itself from the EPMD by simply closing the
TCP connection towards EPMD established when the node was registered.
</p>
</section>
diff --git a/erts/doc/src/erl_driver.xml b/erts/doc/src/erl_driver.xml
index 5061230a33..497a2fa01d 100644
--- a/erts/doc/src/erl_driver.xml
+++ b/erts/doc/src/erl_driver.xml
@@ -781,7 +781,7 @@ typedef struct ErlIOVec {
<marker id="driver_get_now"></marker>
<p>This function reads a timestamp into the memory pointed to by
the parameter <c>now</c>. See the description of <seealso marker="#ErlDrvNowData">ErlDrvNowData</seealso> for
- specification of it's fields. </p>
+ specification of its fields. </p>
<p>The return value is 0 unless the <c>now</c> pointer is not
valid, in which case it is &lt; 0. </p>
</desc>
diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml
index 46f8df4683..c95a7005ec 100644
--- a/erts/doc/src/erlang.xml
+++ b/erts/doc/src/erlang.xml
@@ -2749,7 +2749,7 @@ os_prompt%</pre>
<item>
<p>Works like <c>{spawn, Command}</c>, but only runs
- external executables. The <c>Command</c> in it's whole
+ external executables. The <c>Command</c> in its whole
is used as the name of the executable, including any
spaces. If arguments are to be passed, the
<c>args</c> and <c>arg0</c> <c>PortSettings</c> can be used.</p>
@@ -2926,7 +2926,7 @@ os_prompt%</pre>
The standard input and standard output handles of the port program
will, if this option is supplied, be opened with the flag
FILE_FLAG_OVERLAPPED, so that the port program can (and has to) do
- overlapped I/O on it's standard handles. This is not normally
+ overlapped I/O on its standard handles. This is not normally
the case for simple port programs, but an option of value for the
experienced Windows programmer. <em>On all other platforms, this
option is silently discarded</em>.</p>
@@ -5850,9 +5850,23 @@ true</pre>
</item>
<tag><c>wordsize</c></tag>
<item>
- <p>Returns the word size in bytes as an integer, i.e. on a
- 32-bit architecture 4 is returned, and on a 64-bit
- architecture 8 is returned.</p>
+ <p>Same as <c>{wordsize, internal}</c></p>
+ </item>
+ <tag><c>{wordsize, internal}</c></tag>
+ <item>
+ <p>Returns the size of Erlang term words in bytes as an
+ integer, i.e. on a 32-bit architecture 4 is returned,
+ and on a pure 64-bit architecture 8 is returned. On a
+ halfword 64-bit emulator, 4 is returned, as the Erlang
+ terms are stored using a virtual wordsize of half the
+ systems wordsize.</p>
+ </item>
+ <tag><c>{wordsize, external}</c></tag>
+ <item>
+ <p>Returns the true wordsize of the emulator, i.e. the size
+ of a pointer, in bytes as an integer. On a pure 32-bit
+ architecture 4 is returned, on both a halfword and pure
+ 64-bit architecture, 8 is returned.</p>
</item>
</taglist>
<note>
diff --git a/erts/doc/src/escript.xml b/erts/doc/src/escript.xml
index a89449df23..44c9a5ac68 100644
--- a/erts/doc/src/escript.xml
+++ b/erts/doc/src/escript.xml
@@ -31,7 +31,7 @@
<com>escript</com>
<comsummary>Erlang scripting support</comsummary>
<description>
- <p><c><![CDATA[escript]]></c> provides support for running short Erlang programs
+ <p><c>escript</c> provides support for running short Erlang programs
without having to compile them first and an easy way to retrieve the
command line arguments.</p>
</description>
@@ -41,10 +41,10 @@
<name>escript escript-flags script-name script-arg1 script-arg2...</name>
<fsummary>Run a script written in Erlang</fsummary>
<desc>
- <p><c><![CDATA[escript]]></c> runs a script written in Erlang.</p>
+ <p><c>escript</c> runs a script written in Erlang.</p>
<p>Here follows an example.</p>
<pre>
-$ <input>cat factorial</input>
+$ <input>cat factorial</input>
#!/usr/bin/env escript
%% -*- erlang -*-
%%! -smp enable -sname factorial -mnesia debug verbose
@@ -59,11 +59,11 @@ main([String]) ->
end;
main(_) ->
usage().
-
+
usage() ->
io:format("usage: factorial integer\n"),
halt(1).
-
+
fac(0) -> 1;
fac(N) -> N * fac(N-1).
$ <input>factorial 5</input>
@@ -74,9 +74,8 @@ $ <input>factorial five</input>
usage: factorial integer </pre>
<p>The header of the Erlang script in the example differs from
a normal Erlang module. The first line is intended to be the
- interpreter line, which invokes
- <c><![CDATA[escript]]></c>. However if you invoke the
- <c><![CDATA[escript]]></c> like this</p>
+ interpreter line, which invokes <c>escript</c>. However if you
+ invoke the <c>escript</c> like this</p>
<pre>
$ <input>escript factorial 5</input> </pre>
<p>the contents of the first line does not matter, but it
@@ -93,13 +92,13 @@ $ <input>escript factorial 5</input> </pre>
%%! -smp enable -sname factorial -mnesia debug verbose</pre>
<p>Such an argument line must start with <c>%%!</c> and the
rest of the line will interpreted as arguments to the emulator.</p>
- <p>If you know the location of the <c><![CDATA[escript]]></c> executable, the first
- line can directly give the path to <c><![CDATA[escript]]></c>. For instance:</p>
+ <p>If you know the location of the <c>escript</c> executable, the first
+ line can directly give the path to <c>escript</c>. For instance:</p>
<pre>
#!/usr/local/bin/escript </pre>
<p>As any other kind of scripts, Erlang scripts will not work on
Unix platforms if the execution bit for the script file is not set.
- (Use <c><![CDATA[chmod +x script-name]]></c> to turn on the execution bit.)
+ (Use <c>chmod +x script-name</c> to turn on the execution bit.)
</p>
<p>The rest of the Erlang script file may either contain
@@ -108,33 +107,33 @@ $ <input>escript factorial 5</input> </pre>
<p>An Erlang script file must always contain the function
<em>main/1</em>. When the script is run, the
- <c><![CDATA[main/1]]></c> function will be called with a list
+ <c>main/1</c> function will be called with a list
of strings representing the arguments given to the script (not
changed or interpreted in any way).</p>
- <p>If the <c><![CDATA[main/1]]></c> function in the script returns successfully,
+ <p>If the <c>main/1</c> function in the script returns successfully,
the exit status for the script will be 0. If an exception is generated
during execution, a short message will be printed and the script terminated
with exit status 127.</p>
- <p>To return your own non-zero exit code, call <c><![CDATA[halt(ExitCode)]]></c>;
+ <p>To return your own non-zero exit code, call <c>halt(ExitCode)</c>;
for instance:</p>
<pre>
halt(1).</pre>
- <p>Call <c><![CDATA[escript:script_name/0]]></c> from your to
- script to retrieve the pathname of the script (the pathname
- is usually, but not always, absolute).</p>
+ <p>Call <seealso marker="#script_name_0">escript:script_name()</seealso>
+ from your to script to retrieve the pathname of the script
+ (the pathname is usually, but not always, absolute).</p>
<p>If the file contains source code (as in the example above),
it will be processed by the preprocessor <c>epp</c>. This
means that you for example may use pre-defined macros (such as
- <c><![CDATA[?MODULE]]></c>) as well as include directives like
- the <c><![CDATA[-include_lib]]></c> directive. For instance, use</p>
+ <c>?MODULE</c>) as well as include directives like
+ the <c>-include_lib</c> directive. For instance, use</p>
<pre>
--include_lib("kernel/include/file.hrl"). </pre>
+-include_lib("kernel/include/file.hrl").</pre>
<p>to include the record definitions for the records used by the
- <c><![CDATA[file:read_link_info/1]]></c> function.</p>
+ <c>file:read_link_info/1</c> function.</p>
<p>The script will be checked for syntactic and semantic
correctness before being run. If there are warnings (such as
@@ -144,7 +143,7 @@ halt(1).</pre>
127.</p>
<p>Both the module declaration and the export declaration of
- the <c><![CDATA[main/1]]></c> function are optional.</p>
+ the <c>main/1</c> function are optional.</p>
<p>By default, the script will be interpreted. You can force
it to be compiled by including the following line somewhere
@@ -198,6 +197,180 @@ factorial 5 = 120
</pre>
</desc>
</func>
+ <func>
+ <name>escript:create(FileOrBin, Sections) -> ok | {ok, binary()} | {error, term()}</name>
+ <fsummary>Create an escript</fsummary>
+ <type>
+ <v>FileOrBin = filename() | 'binary'</v>
+ <v>Sections = [Header] Body | Body</v>
+ <v>Header = shebang | {shebang, Shebang}
+ | comment | {comment, Comment}
+ | {emu_args, EmuArgs}</v>
+ <v>Shebang = string() | 'default' | 'undefined'</v>
+ <v>Comment = string() | 'default' | 'undefined'</v>
+ <v>EmuArgs = string() | 'undefined'</v>
+ <v>Body = {source, SourceCode}
+ | {beam, BeamCode}
+ | {archive, ZipArchive}</v>
+ <v>SourceCode = BeamCode = ZipArchive = binary()</v>
+ </type>
+ <desc>
+ <p>The <marker id="create_2"></marker> <c>create/2</c>
+ function creates an escript from a list of sections. The
+ sections can be given in any order. An escript begins with an
+ optional <c>Header</c> followed by a mandatory <c>Body</c>. If
+ the header is present, it does always begin with a
+ <c>shebang</c>, possibly followed by a <c>comment</c> and
+ <c>emu_args</c>. The <c>shebang</c> defaults to
+ <c>"/usr/bin/env escript"</c>. The comment defaults to
+ <c>"This is an -*- erlang -*- file"</c>. The created escript
+ can either be returned as a binary or written to file.</p>
+
+ <p>As an example of how the function can be used, we create an
+ interpreted escript which uses emu_args to set some emulator
+ flag. In this case it happens to disable the smp_support. We
+ do also extract the different sections from the newly created
+ script:</p>
+ <pre>
+&gt; <input>Source = "%% Demo\nmain(_Args) ->\n io:format(erlang:system_info(smp_support)).\n".</input>
+"%% Demo\nmain(_Args) ->\n io:format(erlang:system_info(smp_support)).\n"
+&gt; <input>io:format("~s\n", [Source]).</input>
+%% Demo
+main(_Args) ->
+ io:format(erlang:system_info(smp_support)).
+
+ok
+&gt; <input>{ok, Bin} = escript:create(binary, [shebang, comment, {emu_args, "-smp disable"},
+ {source, list_to_binary(Source)}]).</input>
+{ok,&lt;&lt;"#!/usr/bin/env escript\n%% This is an -*- erlang -*- file\n%%!-smp disabl"...&gt;&gt;}
+&gt; <input>file:write_file("demo.escript", Bin).</input>
+ok
+&gt; <input>os:cmd("escript demo.escript").</input>
+"false"
+&gt; <input>escript:extract("demo.escript", []).</input>
+{ok,[{shebang,default}, {comment,default}, {emu_args,"-smp disable"},
+ {source,&lt;&lt;"%% Demo\nmain(_Args) ->\n io:format(erlang:system_info(smp_su"...&gt;&gt;}]}
+ </pre>
+
+ <p>An escript without header can be created like this:</p>
+<pre>
+&gt; <input>file:write_file("demo.erl",
+ ["%% demo.erl\n-module(demo).\n-export([main/1]).\n\n", Source]).</input>
+ok
+&gt; <input>{ok, _, BeamCode} = compile:file("demo.erl", [binary, debug_info]).</input>
+{ok,demo,
+ &lt;&lt;70,79,82,49,0,0,2,208,66,69,65,77,65,116,111,109,0,0,0,
+ 79,0,0,0,9,4,100,...&gt;&gt;}
+&gt; <input>escript:create("demo.beam", [{beam, BeamCode}]).</input>
+ok
+&gt; <input>escript:extract("demo.beam", []).</input>
+{ok,[{shebang,undefined}, {comment,undefined}, {emu_args,undefined},
+ {beam,&lt;&lt;70,79,82,49,0,0,3,68,66,69,65,77,65,116,
+ 111,109,0,0,0,83,0,0,0,9,...&gt;&gt;}]}
+&gt; <input>os:cmd("escript demo.beam").</input>
+"true"
+</pre>
+ <p>Here we create an archive script containing both Erlang
+ code as well as beam code. Then we iterate over all files in
+ the archive and collect their contents and some info about
+ them.
+ </p>
+<pre>
+&gt; <input>{ok, SourceCode} = file:read_file("demo.erl").</input>
+{ok,&lt;&lt;"%% demo.erl\n-module(demo).\n-export([main/1]).\n\n%% Demo\nmain(_Arg"...&gt;&gt;}
+&gt; <input>escript:create("demo.escript",
+ [shebang,
+ {archive, [{"demo.erl", SourceCode},
+ {"demo.beam", BeamCode}], []}]).</input>
+ok
+&gt; <input>{ok, [{shebang,default}, {comment,undefined}, {emu_args,undefined},
+ {archive, ArchiveBin}]} = escript:extract("demo.escript", []).</input>
+{ok,[{shebang,default}, {comment,undefined}, {emu_args,undefined},
+ {{archive,&lt;&lt;80,75,3,4,20,0,0,0,8,0,118,7,98,60,105,
+ 152,61,93,107,0,0,0,118,0,...&gt;&gt;}]}
+&gt; <input>file:write_file("demo.zip", ArchiveBin).</input>
+ok
+&gt; <input>zip:foldl(fun(N, I, B, A) -> [{N, I(), B()} | A] end, [], "demo.zip").</input>
+{ok,[{"demo.beam",
+ {file_info,748,regular,read_write,
+ {{2010,3,2},{0,59,22}},
+ {{2010,3,2},{0,59,22}},
+ {{2010,3,2},{0,59,22}},
+ 54,1,0,0,0,0,0},
+ &lt;&lt;70,79,82,49,0,0,2,228,66,69,65,77,65,116,111,109,0,0,0,
+ 83,0,0,...&gt;&gt;},
+ {"demo.erl",
+ {file_info,118,regular,read_write,
+ {{2010,3,2},{0,59,22}},
+ {{2010,3,2},{0,59,22}},
+ {{2010,3,2},{0,59,22}},
+ 54,1,0,0,0,0,0},
+ &lt;&lt;"%% demo.erl\n-module(demo).\n-export([main/1]).\n\n%% Demo\nmain(_Arg"...&gt;&gt;}]}</pre>
+ </desc>
+ </func>
+ <func>
+ <name>escript:extract(File, Options) -> {ok, Sections} | {error, term()}</name>
+ <fsummary>Parses an escript and extracts its sections</fsummary>
+ <type>
+ <v>File = filename()</v>
+ <v>Options = [] | [compile_source]</v>
+ <v>Sections = Headers Body</v>
+ <v>Headers = {shebang, Shebang}
+ {comment, Comment}
+ {emu_args, EmuArgs}</v>
+ <v>Shebang = string() | 'default' | 'undefined'</v>
+ <v>Comment = string() | 'default' | 'undefined'</v>
+ <v>EmuArgs = string() | 'undefined'</v>
+ <v>Body = {source, SourceCode}
+ | {source, BeamCode}
+ | {beam, BeamCode}
+ | {archive, ZipArchive}</v>
+ <v>SourceCode = BeamCode = ZipArchive = binary()</v>
+ </type>
+ <desc>
+ <p>The <marker id="extract_2"></marker> <c>extract/2</c>
+ function parses an escript and extracts its sections. This is
+ the reverse of <c>create/2</c>.</p>
+
+ <p>All sections are returned even if they do not exist in the
+ escript. If a particular section happens to have the same
+ value as the default value, the extracted value is set to the
+ atom <c>default</c>. If a section is missing, the extracted
+ value is set to the atom <c>undefined</c>. </p>
+
+ <p>The <c>compile_source</c> option only affects the result if
+ the escript contains <c>source</c> code. In that case the
+ Erlang code is automatically compiled and <c>{source,
+ BeamCode}</c> is returned instead of <c>{source,
+ SourceCode}</c>.</p>
+
+ <pre>
+&gt; <input>escript:create("demo.escript",
+ [shebang, {archive, [{"demo.erl", SourceCode},
+ {"demo.beam", BeamCode}], []}]).</input>
+ok
+&gt; <input>{ok, [{shebang,default}, {comment,undefined}, {emu_args,undefined},
+ {archive, ArchiveBin}]} =
+ escript:extract("demo.escript", []).</input>
+{ok,[{{archive,&lt;&lt;80,75,3,4,20,0,0,0,8,0,118,7,98,60,105,
+ 152,61,93,107,0,0,0,118,0,...&gt;&gt;}
+ {emu_args,undefined}]}
+ </pre>
+ </desc>
+ </func>
+ <func>
+ <name>escript:script_name() -> File</name>
+ <fsummary>Returns the name of an escript</fsummary>
+ <type>
+ <v>File = filename()</v>
+ </type>
+ <desc>
+ <p>The <marker id="script_name_0"></marker>
+ <c>script_name/0</c> function returns the name of the escript
+ being executed. If the function is invoked outside the context
+ of an escript, the behavior is undefined.</p>
+ </desc>
+ </func>
</funcs>
<section>
diff --git a/erts/doc/src/notes.xml b/erts/doc/src/notes.xml
index 65b836fc45..c11509131c 100644
--- a/erts/doc/src/notes.xml
+++ b/erts/doc/src/notes.xml
@@ -4681,7 +4681,7 @@
</item>
<item>
<p>The runtime system with SMP support did not slowly adjust
- it's view of time when the system time suddenly changed.</p>
+ its view of time when the system time suddenly changed.</p>
<p>Timeouts could sometimes timeout too early on the runtime
system with SMP support.</p>
<p>Own Id: OTP-6202</p>
diff --git a/erts/emulator/beam/atom.names b/erts/emulator/beam/atom.names
index 57c8b08223..9ce21089ba 100644
--- a/erts/emulator/beam/atom.names
+++ b/erts/emulator/beam/atom.names
@@ -256,6 +256,7 @@ atom info
atom info_msg
atom initial_call
atom input
+atom internal
atom internal_error
atom internal_status
atom instruction_counts
diff --git a/erts/emulator/beam/beam_bif_load.c b/erts/emulator/beam/beam_bif_load.c
index b1feec7074..8462f1c7fd 100644
--- a/erts/emulator/beam/beam_bif_load.c
+++ b/erts/emulator/beam/beam_bif_load.c
@@ -39,10 +39,10 @@ static Eterm check_process_code(Process* rp, Module* modp);
static void delete_code(Process *c_p, ErtsProcLocks c_p_locks, Module* modp);
static void delete_export_references(Eterm module);
static int purge_module(int module);
-static int is_native(Eterm* code);
+static int is_native(BeamInstr* code);
static int any_heap_ref_ptrs(Eterm* start, Eterm* end, char* mod_start, Uint mod_size);
static int any_heap_refs(Eterm* start, Eterm* end, char* mod_start, Uint mod_size);
-static void remove_from_address_table(Eterm* code);
+static void remove_from_address_table(BeamInstr* code);
Eterm
load_module_2(BIF_ALIST_2)
@@ -344,8 +344,8 @@ BIF_RETTYPE finish_after_on_load_2(BIF_ALIST_2)
modp->code[MI_ON_LOAD_FUNCTION_PTR] = 0;
set_default_trace_pattern(BIF_ARG_1);
} else if (BIF_ARG_2 == am_false) {
- Eterm* code;
- Eterm* end;
+ BeamInstr* code;
+ BeamInstr* end;
/*
* The on_load function failed. Remove the loaded code.
@@ -354,7 +354,7 @@ BIF_RETTYPE finish_after_on_load_2(BIF_ALIST_2)
*/
erts_total_code_size -= modp->code_length;
code = modp->code;
- end = (Eterm *)((char *)code + modp->code_length);
+ end = (BeamInstr *)((char *)code + modp->code_length);
erts_cleanup_funs_on_purge(code, end);
beam_catches_delmod(modp->catches, code, modp->code_length);
erts_free(ERTS_ALC_T_CODE, (void *) code);
@@ -397,10 +397,10 @@ set_default_trace_pattern(Eterm module)
static Eterm
check_process_code(Process* rp, Module* modp)
{
- Eterm* start;
+ BeamInstr* start;
char* mod_start;
Uint mod_size;
- Eterm* end;
+ BeamInstr* end;
Eterm* sp;
#ifndef HYBRID /* FIND ME! */
ErlFunThing* funp;
@@ -418,7 +418,7 @@ check_process_code(Process* rp, Module* modp)
* Pick up limits for the module.
*/
start = modp->old_code;
- end = (Eterm *)((char *)start + modp->old_code_length);
+ end = (BeamInstr *)((char *)start + modp->old_code_length);
mod_start = (char *) start;
mod_size = modp->old_code_length;
@@ -472,11 +472,11 @@ check_process_code(Process* rp, Module* modp)
#ifndef HYBRID /* FIND ME! */
rescan:
for (funp = MSO(rp).funs; funp; funp = funp->next) {
- Eterm* fun_code;
+ BeamInstr* fun_code;
fun_code = funp->fe->address;
- if (INSIDE((Eterm *) funp->fe->address)) {
+ if (INSIDE((BeamInstr *) funp->fe->address)) {
if (done_gc) {
return am_true;
} else {
@@ -576,7 +576,7 @@ any_heap_ref_ptrs(Eterm* start, Eterm* end, char* mod_start, Uint mod_size)
switch (primary_tag(val)) {
case TAG_PRIMARY_BOXED:
case TAG_PRIMARY_LIST:
- if (in_area(val, mod_start, mod_size)) {
+ if (in_area(EXPAND_POINTER(val), mod_start, mod_size)) {
return 1;
}
break;
@@ -596,7 +596,7 @@ any_heap_refs(Eterm* start, Eterm* end, char* mod_start, Uint mod_size)
switch (primary_tag(val)) {
case TAG_PRIMARY_BOXED:
case TAG_PRIMARY_LIST:
- if (in_area(val, mod_start, mod_size)) {
+ if (in_area(EXPAND_POINTER(val), mod_start, mod_size)) {
return 1;
}
break;
@@ -617,8 +617,8 @@ any_heap_refs(Eterm* start, Eterm* end, char* mod_start, Uint mod_size)
static int
purge_module(int module)
{
- Eterm* code;
- Eterm* end;
+ BeamInstr* code;
+ BeamInstr* end;
Module* modp;
/*
@@ -653,7 +653,7 @@ purge_module(int module)
ASSERT(erts_total_code_size >= modp->old_code_length);
erts_total_code_size -= modp->old_code_length;
code = modp->old_code;
- end = (Eterm *)((char *)code + modp->old_code_length);
+ end = (BeamInstr *)((char *)code + modp->old_code_length);
erts_cleanup_funs_on_purge(code, end);
beam_catches_delmod(modp->old_catches, code, modp->old_code_length);
erts_free(ERTS_ALC_T_CODE, (void *) code);
@@ -665,7 +665,7 @@ purge_module(int module)
}
static void
-remove_from_address_table(Eterm* code)
+remove_from_address_table(BeamInstr* code)
{
int i;
@@ -738,11 +738,11 @@ delete_export_references(Eterm module)
Export *ep = export_list(i);
if (ep != NULL && (ep->code[0] == module)) {
if (ep->address == ep->code+3 &&
- (ep->code[3] == (Eterm) em_apply_bif)) {
+ (ep->code[3] == (BeamInstr) em_apply_bif)) {
continue;
}
ep->address = ep->code+3;
- ep->code[3] = (Uint) em_call_error_handler;
+ ep->code[3] = (BeamInstr) em_call_error_handler;
ep->code[4] = 0;
MatchSetUnref(ep->match_prog_set);
ep->match_prog_set = NULL;
@@ -774,7 +774,7 @@ beam_make_current_old(Process *c_p, ErtsProcLocks c_p_locks, Eterm module)
}
static int
-is_native(Eterm* code)
+is_native(BeamInstr* code)
{
return ((Eterm *)code[MI_FUNCTIONS])[1] != 0;
}
diff --git a/erts/emulator/beam/beam_bp.c b/erts/emulator/beam/beam_bp.c
index 1abf1dc10c..6278ff6bad 100644
--- a/erts/emulator/beam/beam_bp.c
+++ b/erts/emulator/beam/beam_bp.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2000-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2000-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -109,23 +109,23 @@ do { \
*/
static int set_break(Eterm mfa[3], int specified,
- Binary *match_spec, Uint break_op,
+ Binary *match_spec, BeamInstr break_op,
enum erts_break_op count_op, Eterm tracer_pid);
static int set_module_break(Module *modp, Eterm mfa[3], int specified,
- Binary *match_spec, Uint break_op,
+ Binary *match_spec, BeamInstr break_op,
enum erts_break_op count_op, Eterm tracer_pid);
-static int set_function_break(Module *modp, Uint *pc,
- Binary *match_spec, Uint break_op,
+static int set_function_break(Module *modp, BeamInstr *pc,
+ Binary *match_spec, BeamInstr break_op,
enum erts_break_op count_op, Eterm tracer_pid);
static int clear_break(Eterm mfa[3], int specified,
- Uint break_op);
+ BeamInstr break_op);
static int clear_module_break(Module *modp, Eterm mfa[3], int specified,
- Uint break_op);
-static int clear_function_break(Module *modp, Uint *pc,
- Uint break_op);
+ BeamInstr break_op);
+static int clear_function_break(Module *modp, BeamInstr *pc,
+ BeamInstr break_op);
-static BpData *is_break(Uint *pc, Uint break_op);
+static BpData *is_break(BeamInstr *pc, BeamInstr break_op);
@@ -145,7 +145,7 @@ erts_set_trace_break(Eterm mfa[3], int specified, Binary *match_spec,
Eterm tracer_pid) {
ERTS_SMP_LC_ASSERT(erts_smp_is_system_blocked(0));
return set_break(mfa, specified, match_spec,
- (Uint) BeamOp(op_i_trace_breakpoint), 0, tracer_pid);
+ (BeamInstr) BeamOp(op_i_trace_breakpoint), 0, tracer_pid);
}
int
@@ -153,11 +153,11 @@ erts_set_mtrace_break(Eterm mfa[3], int specified, Binary *match_spec,
Eterm tracer_pid) {
ERTS_SMP_LC_ASSERT(erts_smp_is_system_blocked(0));
return set_break(mfa, specified, match_spec,
- (Uint) BeamOp(op_i_mtrace_breakpoint), 0, tracer_pid);
+ (BeamInstr) BeamOp(op_i_mtrace_breakpoint), 0, tracer_pid);
}
void
-erts_set_mtrace_bif(Uint *pc, Binary *match_spec, Eterm tracer_pid) {
+erts_set_mtrace_bif(BeamInstr *pc, Binary *match_spec, Eterm tracer_pid) {
BpDataTrace *bdt;
ERTS_SMP_LC_ASSERT(erts_smp_is_system_blocked(0));
@@ -173,7 +173,7 @@ erts_set_mtrace_bif(Uint *pc, Binary *match_spec, Eterm tracer_pid) {
MatchSetRef(match_spec);
bdt->match_spec = match_spec;
bdt->tracer_pid = tracer_pid;
- pc[-4] = (Uint) bdt;
+ pc[-4] = (BeamInstr) bdt;
}
}
@@ -181,14 +181,14 @@ int
erts_set_debug_break(Eterm mfa[3], int specified) {
ERTS_SMP_LC_ASSERT(erts_smp_is_system_blocked(0));
return set_break(mfa, specified, NULL,
- (Uint) BeamOp(op_i_debug_breakpoint), 0, NIL);
+ (BeamInstr) BeamOp(op_i_debug_breakpoint), 0, NIL);
}
int
erts_set_count_break(Eterm mfa[3], int specified, enum erts_break_op count_op) {
ERTS_SMP_LC_ASSERT(erts_smp_is_system_blocked(0));
return set_break(mfa, specified, NULL,
- (Uint) BeamOp(op_i_count_breakpoint), count_op, NIL);
+ (BeamInstr) BeamOp(op_i_count_breakpoint), count_op, NIL);
}
@@ -197,18 +197,18 @@ int
erts_clear_trace_break(Eterm mfa[3], int specified) {
ERTS_SMP_LC_ASSERT(erts_smp_is_system_blocked(0));
return clear_break(mfa, specified,
- (Uint) BeamOp(op_i_trace_breakpoint));
+ (BeamInstr) BeamOp(op_i_trace_breakpoint));
}
int
erts_clear_mtrace_break(Eterm mfa[3], int specified) {
ERTS_SMP_LC_ASSERT(erts_smp_is_system_blocked(0));
return clear_break(mfa, specified,
- (Uint) BeamOp(op_i_mtrace_breakpoint));
+ (BeamInstr) BeamOp(op_i_mtrace_breakpoint));
}
void
-erts_clear_mtrace_bif(Uint *pc) {
+erts_clear_mtrace_bif(BeamInstr *pc) {
BpDataTrace *bdt;
ERTS_SMP_LC_ASSERT(erts_smp_is_system_blocked(0));
@@ -219,21 +219,21 @@ erts_clear_mtrace_bif(Uint *pc) {
}
Free(bdt);
}
- pc[-4] = (Uint) NULL;
+ pc[-4] = (BeamInstr) NULL;
}
int
erts_clear_debug_break(Eterm mfa[3], int specified) {
ERTS_SMP_LC_ASSERT(erts_smp_is_system_blocked(0));
return clear_break(mfa, specified,
- (Uint) BeamOp(op_i_debug_breakpoint));
+ (BeamInstr) BeamOp(op_i_debug_breakpoint));
}
int
erts_clear_count_break(Eterm mfa[3], int specified) {
ERTS_SMP_LC_ASSERT(erts_smp_is_system_blocked(0));
return clear_break(mfa, specified,
- (Uint) BeamOp(op_i_count_breakpoint));
+ (BeamInstr) BeamOp(op_i_count_breakpoint));
}
int
@@ -250,7 +250,7 @@ erts_clear_module_break(Module *modp) {
}
int
-erts_clear_function_break(Module *modp, Uint *pc) {
+erts_clear_function_break(Module *modp, BeamInstr *pc) {
ERTS_SMP_LC_ASSERT(erts_smp_is_system_blocked(0));
ASSERT(modp);
return clear_function_break(modp, pc, 0);
@@ -261,13 +261,13 @@ erts_clear_function_break(Module *modp, Uint *pc) {
/*
* SMP NOTE: Process p may have become exiting on return!
*/
-Uint
-erts_trace_break(Process *p, Uint *pc, Eterm *args,
+BeamInstr
+erts_trace_break(Process *p, BeamInstr *pc, Eterm *args,
Uint32 *ret_flags, Eterm *tracer_pid) {
Eterm tpid1, tpid2;
BpDataTrace *bdt = (BpDataTrace *) pc[-4];
-
- ASSERT(pc[-5] == (Uint) BeamOp(op_i_func_info_IaaI));
+
+ ASSERT(pc[-5] == (BeamInstr) BeamOp(op_i_func_info_IaaI));
ASSERT(bdt);
bdt = (BpDataTrace *) bdt->next;
ASSERT(bdt);
@@ -286,7 +286,7 @@ erts_trace_break(Process *p, Uint *pc, Eterm *args,
bdt->tracer_pid = tpid2;
ErtsSmpBPUnlock(bdt);
}
- pc[-4] = (Uint) bdt;
+ pc[-4] = (BeamInstr) bdt;
return bdt->orig_instr;
}
@@ -296,10 +296,10 @@ erts_trace_break(Process *p, Uint *pc, Eterm *args,
* SMP NOTE: Process p may have become exiting on return!
*/
Uint32
-erts_bif_mtrace(Process *p, Uint *pc, Eterm *args, int local,
+erts_bif_mtrace(Process *p, BeamInstr *pc, Eterm *args, int local,
Eterm *tracer_pid) {
BpDataTrace *bdt = (BpDataTrace *) pc[-4];
-
+
ASSERT(tracer_pid);
if (bdt) {
Eterm tpid1, tpid2;
@@ -326,9 +326,9 @@ erts_bif_mtrace(Process *p, Uint *pc, Eterm *args, int local,
int
-erts_is_trace_break(Uint *pc, Binary **match_spec_ret, Eterm *tracer_pid_ret) {
+erts_is_trace_break(BeamInstr *pc, Binary **match_spec_ret, Eterm *tracer_pid_ret) {
BpDataTrace *bdt =
- (BpDataTrace *) is_break(pc, (Uint) BeamOp(op_i_trace_breakpoint));
+ (BpDataTrace *) is_break(pc, (BeamInstr) BeamOp(op_i_trace_breakpoint));
if (bdt) {
if (match_spec_ret) {
@@ -345,9 +345,9 @@ erts_is_trace_break(Uint *pc, Binary **match_spec_ret, Eterm *tracer_pid_ret) {
}
int
-erts_is_mtrace_break(Uint *pc, Binary **match_spec_ret, Eterm *tracer_pid_ret) {
+erts_is_mtrace_break(BeamInstr *pc, Binary **match_spec_ret, Eterm *tracer_pid_ret) {
BpDataTrace *bdt =
- (BpDataTrace *) is_break(pc, (Uint) BeamOp(op_i_mtrace_breakpoint));
+ (BpDataTrace *) is_break(pc, (BeamInstr) BeamOp(op_i_mtrace_breakpoint));
if (bdt) {
if (match_spec_ret) {
@@ -364,7 +364,7 @@ erts_is_mtrace_break(Uint *pc, Binary **match_spec_ret, Eterm *tracer_pid_ret) {
}
int
-erts_is_mtrace_bif(Uint *pc, Binary **match_spec_ret, Eterm *tracer_pid_ret) {
+erts_is_mtrace_bif(BeamInstr *pc, Binary **match_spec_ret, Eterm *tracer_pid_ret) {
BpDataTrace *bdt = (BpDataTrace *) pc[-4];
if (bdt) {
@@ -382,20 +382,20 @@ erts_is_mtrace_bif(Uint *pc, Binary **match_spec_ret, Eterm *tracer_pid_ret) {
}
int
-erts_is_native_break(Uint *pc) {
+erts_is_native_break(BeamInstr *pc) {
#ifdef HIPE
- ASSERT(pc[-5] == (Uint) BeamOp(op_i_func_info_IaaI));
- return pc[0] == (Uint) BeamOp(op_hipe_trap_call)
- || pc[0] == (Uint) BeamOp(op_hipe_trap_call_closure);
+ ASSERT(pc[-5] == (BeamInstr) BeamOp(op_i_func_info_IaaI));
+ return pc[0] == (BeamInstr) BeamOp(op_hipe_trap_call)
+ || pc[0] == (BeamInstr) BeamOp(op_hipe_trap_call_closure);
#else
return 0;
#endif
}
int
-erts_is_count_break(Uint *pc, Sint *count_ret) {
+erts_is_count_break(BeamInstr *pc, Sint *count_ret) {
BpDataCount *bdc =
- (BpDataCount *) is_break(pc, (Uint) BeamOp(op_i_count_breakpoint));
+ (BpDataCount *) is_break(pc, (BeamInstr) BeamOp(op_i_count_breakpoint));
if (bdc) {
if (count_ret) {
@@ -408,24 +408,24 @@ erts_is_count_break(Uint *pc, Sint *count_ret) {
return 0;
}
-Uint *
+BeamInstr *
erts_find_local_func(Eterm mfa[3]) {
Module *modp;
- Uint** code_base;
- Uint* code_ptr;
+ BeamInstr** code_base;
+ BeamInstr* code_ptr;
Uint i,n;
if ((modp = erts_get_module(mfa[0])) == NULL)
return NULL;
- if ((code_base = (Uint **) modp->code) == NULL)
+ if ((code_base = (BeamInstr **) modp->code) == NULL)
return NULL;
- n = (Uint) code_base[MI_NUM_FUNCTIONS];
+ n = (BeamInstr) code_base[MI_NUM_FUNCTIONS];
for (i = 0; i < n; ++i) {
code_ptr = code_base[MI_FUNCTIONS+i];
- ASSERT(((Uint) BeamOp(op_i_func_info_IaaI)) == code_ptr[0]);
+ ASSERT(((BeamInstr) BeamOp(op_i_func_info_IaaI)) == code_ptr[0]);
ASSERT(mfa[0] == ((Eterm) code_ptr[2]));
if (mfa[1] == ((Eterm) code_ptr[3]) &&
- ((Uint) mfa[2]) == code_ptr[4]) {
+ ((BeamInstr) mfa[2]) == code_ptr[4]) {
return code_ptr + 5;
}
}
@@ -440,7 +440,7 @@ erts_find_local_func(Eterm mfa[3]) {
static int set_break(Eterm mfa[3], int specified,
- Binary *match_spec, Eterm break_op,
+ Binary *match_spec, BeamInstr break_op,
enum erts_break_op count_op, Eterm tracer_pid)
{
Module *modp;
@@ -470,26 +470,26 @@ static int set_break(Eterm mfa[3], int specified,
}
static int set_module_break(Module *modp, Eterm mfa[3], int specified,
- Binary *match_spec, Uint break_op,
+ Binary *match_spec, BeamInstr break_op,
enum erts_break_op count_op, Eterm tracer_pid) {
- Uint** code_base;
- Uint* code_ptr;
+ BeamInstr** code_base;
+ BeamInstr* code_ptr;
int num_processed = 0;
Uint i,n;
ASSERT(break_op);
ASSERT(modp);
- code_base = (Uint **) modp->code;
+ code_base = (BeamInstr **) modp->code;
if (code_base == NULL) {
return 0;
}
- n = (Uint) code_base[MI_NUM_FUNCTIONS];
+ n = (BeamInstr) code_base[MI_NUM_FUNCTIONS];
for (i = 0; i < n; ++i) {
code_ptr = code_base[MI_FUNCTIONS+i];
- ASSERT(code_ptr[0] == (Uint) BeamOp(op_i_func_info_IaaI));
+ ASSERT(code_ptr[0] == (BeamInstr) BeamOp(op_i_func_info_IaaI));
if ((specified < 2 || mfa[1] == ((Eterm) code_ptr[3])) &&
(specified < 3 || ((int) mfa[2]) == ((int) code_ptr[4]))) {
- Uint *pc = code_ptr+5;
+ BeamInstr *pc = code_ptr+5;
num_processed +=
set_function_break(modp, pc, match_spec,
@@ -499,16 +499,16 @@ static int set_module_break(Module *modp, Eterm mfa[3], int specified,
return num_processed;
}
-static int set_function_break(Module *modp, Uint *pc,
- Binary *match_spec, Uint break_op,
+static int set_function_break(Module *modp, BeamInstr *pc,
+ Binary *match_spec, BeamInstr break_op,
enum erts_break_op count_op, Eterm tracer_pid) {
BpData *bd, **r;
size_t size;
- Uint **code_base = (Uint **)modp->code;
+ BeamInstr **code_base = (BeamInstr **)modp->code;
ASSERT(code_base);
- ASSERT(code_base <= (Uint **)pc);
- ASSERT((Uint **)pc < code_base + (modp->code_length/sizeof(Uint *)));
+ ASSERT(code_base <= (BeamInstr **)pc);
+ ASSERT((BeamInstr **)pc < code_base + (modp->code_length/sizeof(BeamInstr *)));
/*
* Currently no trace support for native code.
*/
@@ -517,8 +517,8 @@ static int set_function_break(Module *modp, Uint *pc,
}
/* Do not allow two breakpoints of the same kind */
if ( (bd = is_break(pc, break_op))) {
- if (break_op == (Uint) BeamOp(op_i_trace_breakpoint)
- || break_op == (Uint) BeamOp(op_i_mtrace_breakpoint)) {
+ if (break_op == (BeamInstr) BeamOp(op_i_trace_breakpoint)
+ || break_op == (BeamInstr) BeamOp(op_i_mtrace_breakpoint)) {
BpDataTrace *bdt = (BpDataTrace *) bd;
Binary *old_match_spec;
@@ -533,7 +533,7 @@ static int set_function_break(Module *modp, Uint *pc,
} else {
ASSERT(! match_spec);
ASSERT(is_nil(tracer_pid));
- if (break_op == (Uint) BeamOp(op_i_count_breakpoint)) {
+ if (break_op == (BeamInstr) BeamOp(op_i_count_breakpoint)) {
BpDataCount *bdc = (BpDataCount *) bd;
ErtsSmpBPLock(bdc);
@@ -551,13 +551,13 @@ static int set_function_break(Module *modp, Uint *pc,
}
return 1;
}
- if (break_op == (Uint) BeamOp(op_i_trace_breakpoint) ||
- break_op == (Uint) BeamOp(op_i_mtrace_breakpoint)) {
+ if (break_op == (BeamInstr) BeamOp(op_i_trace_breakpoint) ||
+ break_op == (BeamInstr) BeamOp(op_i_mtrace_breakpoint)) {
size = sizeof(BpDataTrace);
} else {
ASSERT(! match_spec);
ASSERT(is_nil(tracer_pid));
- if (break_op == (Uint) BeamOp(op_i_count_breakpoint)) {
+ if (break_op == (BeamInstr) BeamOp(op_i_count_breakpoint)) {
if (count_op == erts_break_reset
|| count_op == erts_break_stop) {
/* Do not insert a new breakpoint */
@@ -566,27 +566,27 @@ static int set_function_break(Module *modp, Uint *pc,
size = sizeof(BpDataCount);
} else {
ASSERT(! count_op);
- ASSERT(break_op == (Uint) BeamOp(op_i_debug_breakpoint));
+ ASSERT(break_op == (BeamInstr) BeamOp(op_i_debug_breakpoint));
size = sizeof(BpDataDebug);
}
}
r = (BpData **) (pc-4);
if (! *r) {
- ASSERT(*pc != (Uint) BeamOp(op_i_trace_breakpoint));
- ASSERT(*pc != (Uint) BeamOp(op_i_mtrace_breakpoint));
- ASSERT(*pc != (Uint) BeamOp(op_i_debug_breakpoint));
- ASSERT(*pc != (Uint) BeamOp(op_i_count_breakpoint));
+ ASSERT(*pc != (BeamInstr) BeamOp(op_i_trace_breakpoint));
+ ASSERT(*pc != (BeamInstr) BeamOp(op_i_mtrace_breakpoint));
+ ASSERT(*pc != (BeamInstr) BeamOp(op_i_debug_breakpoint));
+ ASSERT(*pc != (BeamInstr) BeamOp(op_i_count_breakpoint));
/* First breakpoint; create singleton ring */
bd = Alloc(size);
BpInit(bd, *pc);
*pc = break_op;
*r = bd;
} else {
- ASSERT(*pc == (Uint) BeamOp(op_i_trace_breakpoint) ||
- *pc == (Uint) BeamOp(op_i_mtrace_breakpoint) ||
- *pc == (Uint) BeamOp(op_i_debug_breakpoint) ||
- *pc == (Uint) BeamOp(op_i_count_breakpoint));
- if (*pc == (Uint) BeamOp(op_i_debug_breakpoint)) {
+ ASSERT(*pc == (BeamInstr) BeamOp(op_i_trace_breakpoint) ||
+ *pc == (BeamInstr) BeamOp(op_i_mtrace_breakpoint) ||
+ *pc == (BeamInstr) BeamOp(op_i_debug_breakpoint) ||
+ *pc == (BeamInstr) BeamOp(op_i_count_breakpoint));
+ if (*pc == (BeamInstr) BeamOp(op_i_debug_breakpoint)) {
/* Debug bp must be last, so if it is also first;
* it must be singleton. */
ASSERT(BpSingleton(*r));
@@ -595,7 +595,7 @@ static int set_function_break(Module *modp, Uint *pc,
BpInitAndSpliceNext(bd, *pc, *r);
*pc = break_op;
} else if ((*r)->prev->orig_instr
- == (Uint) BeamOp(op_i_debug_breakpoint)) {
+ == (BeamInstr) BeamOp(op_i_debug_breakpoint)) {
/* Debug bp last in the ring; insert new second to last. */
bd = Alloc(size);
BpInitAndSplicePrev(bd, (*r)->prev->orig_instr, *r);
@@ -609,24 +609,24 @@ static int set_function_break(Module *modp, Uint *pc,
}
}
/* Init the bp type specific data */
- if (break_op == (Uint) BeamOp(op_i_trace_breakpoint) ||
- break_op == (Uint) BeamOp(op_i_mtrace_breakpoint)) {
+ if (break_op == (BeamInstr) BeamOp(op_i_trace_breakpoint) ||
+ break_op == (BeamInstr) BeamOp(op_i_mtrace_breakpoint)) {
BpDataTrace *bdt = (BpDataTrace *) bd;
MatchSetRef(match_spec);
bdt->match_spec = match_spec;
bdt->tracer_pid = tracer_pid;
- } else if (break_op == (Uint) BeamOp(op_i_count_breakpoint)) {
+ } else if (break_op == (BeamInstr) BeamOp(op_i_count_breakpoint)) {
BpDataCount *bdc = (BpDataCount *) bd;
bdc->count = 0;
}
- ++(*(Uint*)&code_base[MI_NUM_BREAKPOINTS]);
+ ++(*(BeamInstr*)&code_base[MI_NUM_BREAKPOINTS]);
return 1;
}
-static int clear_break(Eterm mfa[3], int specified, Uint break_op)
+static int clear_break(Eterm mfa[3], int specified, BeamInstr break_op)
{
int num_processed = 0;
Module *modp;
@@ -652,23 +652,24 @@ static int clear_break(Eterm mfa[3], int specified, Uint break_op)
}
static int clear_module_break(Module *m, Eterm mfa[3], int specified,
- Uint break_op) {
- Uint** code_base;
- Uint* code_ptr;
+ BeamInstr break_op) {
+ BeamInstr** code_base;
+ BeamInstr* code_ptr;
int num_processed = 0;
- Uint i,n;
+ Uint i;
+ BeamInstr n;
ASSERT(m);
- code_base = (Uint **) m->code;
+ code_base = (BeamInstr **) m->code;
if (code_base == NULL) {
return 0;
}
- n = (Uint) code_base[MI_NUM_FUNCTIONS];
+ n = (BeamInstr) code_base[MI_NUM_FUNCTIONS];
for (i = 0; i < n; ++i) {
code_ptr = code_base[MI_FUNCTIONS+i];
if ((specified < 2 || mfa[1] == ((Eterm) code_ptr[3])) &&
(specified < 3 || ((int) mfa[2]) == ((int) code_ptr[4]))) {
- Uint *pc = code_ptr + 5;
+ BeamInstr *pc = code_ptr + 5;
num_processed +=
clear_function_break(m, pc, break_op);
@@ -677,13 +678,13 @@ static int clear_module_break(Module *m, Eterm mfa[3], int specified,
return num_processed;
}
-static int clear_function_break(Module *m, Uint *pc, Uint break_op) {
+static int clear_function_break(Module *m, BeamInstr *pc, BeamInstr break_op) {
BpData *bd;
- Uint **code_base = (Uint **)m->code;
+ BeamInstr **code_base = (BeamInstr **)m->code;
ASSERT(code_base);
- ASSERT(code_base <= (Uint **)pc);
- ASSERT((Uint **)pc < code_base + (m->code_length/sizeof(Uint *)));
+ ASSERT(code_base <= (BeamInstr **)pc);
+ ASSERT((BeamInstr **)pc < code_base + (m->code_length/sizeof(BeamInstr *)));
/*
* Currently no trace support for native code.
*/
@@ -695,7 +696,7 @@ static int clear_function_break(Module *m, Uint *pc, Uint break_op) {
* There should be only one of each type,
* but break_op may be 0 which matches any type.
*/
- Uint op;
+ BeamInstr op;
BpData **r = (BpData **) (pc-4);
ASSERT(*r);
@@ -731,16 +732,16 @@ static int clear_function_break(Module *m, Uint *pc, Uint break_op) {
bd_prev->orig_instr = bd->orig_instr;
}
}
- if (op == (Uint) BeamOp(op_i_trace_breakpoint) ||
- op == (Uint) BeamOp(op_i_mtrace_breakpoint)) {
+ if (op == (BeamInstr) BeamOp(op_i_trace_breakpoint) ||
+ op == (BeamInstr) BeamOp(op_i_mtrace_breakpoint)) {
BpDataTrace *bdt = (BpDataTrace *) bd;
-
+
MatchSetUnref(bdt->match_spec);
}
Free(bd);
- ASSERT(((Uint) code_base[MI_NUM_BREAKPOINTS]) > 0);
- --(*(Uint*)&code_base[MI_NUM_BREAKPOINTS]);
+ ASSERT(((BeamInstr) code_base[MI_NUM_BREAKPOINTS]) > 0);
+ --(*(BeamInstr*)&code_base[MI_NUM_BREAKPOINTS]);
}
return 1;
}
@@ -754,8 +755,8 @@ static int clear_function_break(Module *m, Uint *pc, Uint break_op) {
** returned. The program counter must point to the first executable
** (breakpoint) instruction of the function.
*/
-static BpData *is_break(Uint *pc, Uint break_op) {
- ASSERT(pc[-5] == (Uint) BeamOp(op_i_func_info_IaaI));
+static BpData *is_break(BeamInstr *pc, BeamInstr break_op) {
+ ASSERT(pc[-5] == (BeamInstr) BeamOp(op_i_func_info_IaaI));
if (! erts_is_native_break(pc)) {
BpData *bd = (BpData *) pc[-4];
diff --git a/erts/emulator/beam/beam_bp.h b/erts/emulator/beam/beam_bp.h
index 44e6b294d8..786cbbe9d9 100644
--- a/erts/emulator/beam/beam_bp.h
+++ b/erts/emulator/beam/beam_bp.h
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2000-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2000-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -48,7 +48,7 @@
typedef struct bp_data {
struct bp_data *next; /* Doubly linked ring pointers */
struct bp_data *prev; /* -"- */
- Uint orig_instr; /* The original instruction to execute */
+ BeamInstr orig_instr; /* The original instruction to execute */
} BpData;
/*
** All the following bp_data_.. structs must begin the same way
@@ -57,21 +57,21 @@ typedef struct bp_data {
typedef struct bp_data_trace {
struct bp_data *next;
struct bp_data *prev;
- Uint orig_instr;
+ BeamInstr orig_instr;
Binary *match_spec;
- Eterm tracer_pid;
+ Eterm tracer_pid;
} BpDataTrace;
typedef struct bp_data_debug {
struct bp_data *next;
struct bp_data *prev;
- Uint orig_instr;
+ BeamInstr orig_instr;
} BpDataDebug;
typedef struct bp_data_count { /* Call count */
struct bp_data *next;
struct bp_data *prev;
- Uint orig_instr;
+ BeamInstr orig_instr;
Sint count;
} BpDataCount;
@@ -89,11 +89,11 @@ extern erts_smp_spinlock_t erts_bp_lock;
do { \
BpDataCount *bdc = (BpDataCount *) (pc)[-4]; \
\
- ASSERT((pc)[-5] == (Uint) BeamOp(op_i_func_info_IaaI)); \
+ ASSERT((pc)[-5] == (BeamInstr) BeamOp(op_i_func_info_IaaI)); \
ASSERT(bdc); \
bdc = (BpDataCount *) bdc->next; \
ASSERT(bdc); \
- (pc)[-4] = (Uint) bdc; \
+ (pc)[-4] = (BeamInstr) bdc; \
ErtsSmpBPLock(bdc); \
if (bdc->count >= 0) bdc->count++; \
ErtsSmpBPUnlock(bdc); \
@@ -104,11 +104,11 @@ do { \
do { \
BpData *bd = (BpData *) (pc)[-4]; \
\
- ASSERT((pc)[-5] == (Uint) BeamOp(op_i_func_info_IaaI)); \
+ ASSERT((pc)[-5] == (BeamInstr) BeamOp(op_i_func_info_IaaI)); \
ASSERT(bd); \
bd = bd->next; \
ASSERT(bd); \
- (pc)[-4] = (Uint) bd; \
+ (pc)[-4] = (BeamInstr) bd; \
*(instr_result) = bd->orig_instr; \
} while (0)
@@ -133,9 +133,9 @@ int erts_clear_trace_break(Eterm mfa[3], int specified);
int erts_set_mtrace_break(Eterm mfa[3], int specified, Binary *match_spec,
Eterm tracer_pid);
int erts_clear_mtrace_break(Eterm mfa[3], int specified);
-void erts_set_mtrace_bif(Uint *pc, Binary *match_spec,
+void erts_set_mtrace_bif(BeamInstr *pc, Binary *match_spec,
Eterm tracer_pid);
-void erts_clear_mtrace_bif(Uint *pc);
+void erts_clear_mtrace_bif(BeamInstr *pc);
int erts_set_debug_break(Eterm mfa[3], int specified);
int erts_clear_debug_break(Eterm mfa[3], int specified);
int erts_set_count_break(Eterm mfa[3], int specified, enum erts_break_op);
@@ -144,22 +144,22 @@ int erts_clear_count_break(Eterm mfa[3], int specified);
int erts_clear_break(Eterm mfa[3], int specified);
int erts_clear_module_break(Module *modp);
-int erts_clear_function_break(Module *modp, Uint *pc);
+int erts_clear_function_break(Module *modp, BeamInstr *pc);
-Uint erts_trace_break(Process *p, Uint *pc, Eterm *args,
+BeamInstr erts_trace_break(Process *p, BeamInstr *pc, Eterm *args,
Uint32 *ret_flags, Eterm *tracer_pid);
-Uint32 erts_bif_mtrace(Process *p, Uint *pc, Eterm *args,
+Uint32 erts_bif_mtrace(Process *p, BeamInstr *pc, Eterm *args,
int local, Eterm *tracer_pid);
-int erts_is_trace_break(Uint *pc, Binary **match_spec_ret,
+int erts_is_trace_break(BeamInstr *pc, Binary **match_spec_ret,
Eterm *tracer_pid_ret);
-int erts_is_mtrace_break(Uint *pc, Binary **match_spec_ret,
+int erts_is_mtrace_break(BeamInstr *pc, Binary **match_spec_ret,
Eterm *tracer_pid_rte);
-int erts_is_mtrace_bif(Uint *pc, Binary **match_spec_ret,
+int erts_is_mtrace_bif(BeamInstr *pc, Binary **match_spec_ret,
Eterm *tracer_pid_ret);
-int erts_is_native_break(Uint *pc);
-int erts_is_count_break(Uint *pc, Sint *count_ret);
+int erts_is_native_break(BeamInstr *pc);
+int erts_is_count_break(BeamInstr *pc, Sint *count_ret);
-Uint *erts_find_local_func(Eterm mfa[3]);
+BeamInstr *erts_find_local_func(Eterm mfa[3]);
#endif /* _BEAM_BP_H */
diff --git a/erts/emulator/beam/beam_catches.c b/erts/emulator/beam/beam_catches.c
index d5cef1cad2..e795b4efbd 100644
--- a/erts/emulator/beam/beam_catches.c
+++ b/erts/emulator/beam/beam_catches.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2000-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2000-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -26,7 +26,7 @@
/* XXX: should use dynamic reallocation */
#define TABSIZ (16*1024)
static struct {
- Eterm *cp;
+ BeamInstr *cp;
unsigned cdr;
} beam_catches[TABSIZ];
@@ -39,7 +39,7 @@ void beam_catches_init(void)
high_mark = 0;
}
-unsigned beam_catches_cons(Eterm *cp, unsigned cdr)
+unsigned beam_catches_cons(BeamInstr *cp, unsigned cdr)
{
int i;
@@ -65,7 +65,7 @@ unsigned beam_catches_cons(Eterm *cp, unsigned cdr)
return i;
}
-Eterm *beam_catches_car(unsigned i)
+BeamInstr *beam_catches_car(unsigned i)
{
if( i >= TABSIZ ) {
fprintf(stderr,
@@ -75,7 +75,7 @@ Eterm *beam_catches_car(unsigned i)
return beam_catches[i].cp;
}
-void beam_catches_delmod(unsigned head, Eterm *code, unsigned code_bytes)
+void beam_catches_delmod(unsigned head, BeamInstr *code, unsigned code_bytes)
{
unsigned i, cdr;
diff --git a/erts/emulator/beam/beam_catches.h b/erts/emulator/beam/beam_catches.h
index ccf33d5e86..6223427f0d 100644
--- a/erts/emulator/beam/beam_catches.h
+++ b/erts/emulator/beam/beam_catches.h
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2000-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2000-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -23,9 +23,9 @@
#define BEAM_CATCHES_NIL (-1)
void beam_catches_init(void);
-unsigned beam_catches_cons(Eterm* cp, unsigned cdr);
-Eterm *beam_catches_car(unsigned i);
-void beam_catches_delmod(unsigned head, Eterm* code, unsigned code_bytes);
+unsigned beam_catches_cons(BeamInstr* cp, unsigned cdr);
+BeamInstr *beam_catches_car(unsigned i);
+void beam_catches_delmod(unsigned head, BeamInstr* code, unsigned code_bytes);
#define catch_pc(x) beam_catches_car(catch_val((x)))
diff --git a/erts/emulator/beam/beam_debug.c b/erts/emulator/beam/beam_debug.c
index 4242a4161e..23b267d5cd 100644
--- a/erts/emulator/beam/beam_debug.c
+++ b/erts/emulator/beam/beam_debug.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1998-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1998-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -43,12 +43,13 @@
#else
# define HEXF "%08bpX"
#endif
+#define TermWords(t) (((t) / (sizeof(BeamInstr)/sizeof(Eterm))) + !!((t) % (sizeof(BeamInstr)/sizeof(Eterm))))
void dbg_bt(Process* p, Eterm* sp);
-void dbg_where(Eterm* addr, Eterm x0, Eterm* reg);
+void dbg_where(BeamInstr* addr, Eterm x0, Eterm* reg);
static void print_big(int to, void *to_arg, Eterm* addr);
-static int print_op(int to, void *to_arg, int op, int size, Eterm* addr);
+static int print_op(int to, void *to_arg, int op, int size, BeamInstr* addr);
Eterm
erts_debug_same_2(Process* p, Eterm term1, Eterm term2)
{
@@ -124,6 +125,38 @@ erts_debug_breakpoint_2(Process* p, Eterm MFA, Eterm bool)
BIF_ERROR(p, BADARG);
}
+#if 0 /* XXX:PaN - not used */
+void debug_dump_code(BeamInstr *I, int num)
+{
+ BeamInstr *code_ptr = I;
+ BeamInstr *end = code_ptr + num;
+ erts_dsprintf_buf_t *dsbufp;
+ BeamInstr instr;
+ int i;
+
+ dsbufp = erts_create_tmp_dsbuf(0);
+ while (code_ptr < end) {
+ erts_print(ERTS_PRINT_DSBUF, (void *) dsbufp, HEXF ": ", code_ptr);
+ instr = (BeamInstr) code_ptr[0];
+ for (i = 0; i < NUM_SPECIFIC_OPS; i++) {
+ if (instr == (BeamInstr) BeamOp(i) && opc[i].name[0] != '\0') {
+ code_ptr += print_op(ERTS_PRINT_DSBUF, (void *) dsbufp,
+ i, opc[i].sz-1, code_ptr+1) + 1;
+ break;
+ }
+ }
+ if (i >= NUM_SPECIFIC_OPS) {
+ erts_print(ERTS_PRINT_DSBUF, (void *) dsbufp,
+ "unknown " HEXF "\n", instr);
+ code_ptr++;
+ }
+ }
+ dsbufp->str[dsbufp->str_len] = 0;
+ erts_fprintf(stderr,"%s", dsbufp->str);
+ erts_destroy_tmp_dsbuf(dsbufp);
+}
+#endif
+
Eterm
erts_debug_disassemble_1(Process* p, Eterm addr)
{
@@ -132,16 +165,16 @@ erts_debug_disassemble_1(Process* p, Eterm addr)
Eterm* tp;
Eterm bin;
Eterm mfa;
- Eterm* funcinfo = NULL; /* Initialized to eliminate warning. */
- Uint* code_base;
- Uint* code_ptr = NULL; /* Initialized to eliminate warning. */
- Uint instr;
- Uint uaddr;
+ BeamInstr* funcinfo = NULL; /* Initialized to eliminate warning. */
+ BeamInstr* code_base;
+ BeamInstr* code_ptr = NULL; /* Initialized to eliminate warning. */
+ BeamInstr instr;
+ BeamInstr uaddr;
Uint hsz;
int i;
- if (term_to_Uint(addr, &uaddr)) {
- code_ptr = (Uint *) uaddr;
+ if (term_to_UWord(addr, &uaddr)) {
+ code_ptr = (BeamInstr *) uaddr;
if ((funcinfo = find_function_from_pc(code_ptr)) == NULL) {
BIF_RET(am_false);
}
@@ -180,14 +213,14 @@ erts_debug_disassemble_1(Process* p, Eterm addr)
* But this code_ptr will point to the start of the Export,
* not the function's func_info instruction. BOOM !?
*/
- code_ptr = ((Eterm *) ep->address) - 5;
+ code_ptr = ((BeamInstr *) ep->address) - 5;
funcinfo = code_ptr+2;
} else if (modp == NULL || (code_base = modp->code) == NULL) {
BIF_RET(am_undef);
} else {
n = code_base[MI_NUM_FUNCTIONS];
for (i = 0; i < n; i++) {
- code_ptr = (Uint *) code_base[MI_FUNCTIONS+i];
+ code_ptr = (BeamInstr *) code_base[MI_FUNCTIONS+i];
if (code_ptr[3] == name && code_ptr[4] == arity) {
funcinfo = code_ptr+2;
break;
@@ -203,9 +236,9 @@ erts_debug_disassemble_1(Process* p, Eterm addr)
dsbufp = erts_create_tmp_dsbuf(0);
erts_print(ERTS_PRINT_DSBUF, (void *) dsbufp, HEXF ": ", code_ptr);
- instr = (Uint) code_ptr[0];
+ instr = (BeamInstr) code_ptr[0];
for (i = 0; i < NUM_SPECIFIC_OPS; i++) {
- if (instr == (Uint) BeamOp(i) && opc[i].name[0] != '\0') {
+ if (instr == (BeamInstr) BeamOp(i) && opc[i].name[0] != '\0') {
code_ptr += print_op(ERTS_PRINT_DSBUF, (void *) dsbufp,
i, opc[i].sz-1, code_ptr+1) + 1;
break;
@@ -219,12 +252,12 @@ erts_debug_disassemble_1(Process* p, Eterm addr)
bin = new_binary(p, (byte *) dsbufp->str, (int) dsbufp->str_len);
erts_destroy_tmp_dsbuf(dsbufp);
hsz = 4+4;
- (void) erts_bld_uint(NULL, &hsz, (Uint) code_ptr);
+ (void) erts_bld_uword(NULL, &hsz, (BeamInstr) code_ptr);
hp = HAlloc(p, hsz);
- addr = erts_bld_uint(&hp, NULL, (Uint) code_ptr);
+ addr = erts_bld_uword(&hp, NULL, (BeamInstr) code_ptr);
ASSERT(is_atom(funcinfo[0]));
ASSERT(is_atom(funcinfo[1]));
- mfa = TUPLE3(hp, funcinfo[0], funcinfo[1], make_small(funcinfo[2]));
+ mfa = TUPLE3(hp, (Eterm) funcinfo[0], (Eterm) funcinfo[1], make_small((Eterm) funcinfo[2]));
hp += 4;
return TUPLE3(hp, addr, bin, mfa);
}
@@ -236,20 +269,20 @@ dbg_bt(Process* p, Eterm* sp)
while (sp < stack) {
if (is_CP(*sp)) {
- Eterm* addr = find_function_from_pc(cp_val(*sp));
+ BeamInstr* addr = find_function_from_pc(cp_val(*sp));
if (addr)
erts_fprintf(stderr,
HEXF ": %T:%T/%bpu\n",
- addr, addr[0], addr[1], addr[2]);
+ addr, (Eterm) addr[0], (Eterm) addr[1], (Uint) addr[2]);
}
sp++;
}
}
void
-dbg_where(Eterm* addr, Eterm x0, Eterm* reg)
+dbg_where(BeamInstr* addr, Eterm x0, Eterm* reg)
{
- Eterm* f = find_function_from_pc(addr);
+ BeamInstr* f = find_function_from_pc(addr);
if (f == NULL) {
erts_fprintf(stderr, "???\n");
@@ -259,7 +292,7 @@ dbg_where(Eterm* addr, Eterm x0, Eterm* reg)
addr = f;
arity = addr[2];
- erts_fprintf(stderr, HEXF ": %T:%T(", addr, addr[0], addr[1]);
+ erts_fprintf(stderr, HEXF ": %T:%T(", addr, (Eterm) addr[0], (Eterm) addr[1]);
for (i = 0; i < arity; i++)
erts_fprintf(stderr, i ? ", %T" : "%T", i ? reg[i] : x0);
erts_fprintf(stderr, ")\n");
@@ -267,18 +300,18 @@ dbg_where(Eterm* addr, Eterm x0, Eterm* reg)
}
static int
-print_op(int to, void *to_arg, int op, int size, Eterm* addr)
+print_op(int to, void *to_arg, int op, int size, BeamInstr* addr)
{
int i;
- Uint tag;
+ BeamInstr tag;
char* sign;
char* start_prog; /* Start of program for packer. */
char* prog; /* Current position in packer program. */
- Uint stack[8]; /* Stack for packer. */
- Uint* sp = stack; /* Points to next free position. */
- Uint packed = 0; /* Accumulator for packed operations. */
- Uint args[8]; /* Arguments for this instruction. */
- Uint* ap; /* Pointer to arguments. */
+ BeamInstr stack[8]; /* Stack for packer. */
+ BeamInstr* sp = stack; /* Points to next free position. */
+ BeamInstr packed = 0; /* Accumulator for packed operations. */
+ BeamInstr args[8]; /* Arguments for this instruction. */
+ BeamInstr* ap; /* Pointer to arguments. */
start_prog = opc[op].pack;
@@ -288,7 +321,7 @@ print_op(int to, void *to_arg, int op, int size, Eterm* addr)
* Avoid copying because instructions containing bignum operands
* are bigger than actually declared.
*/
- ap = (Uint *) addr;
+ ap = (BeamInstr *) addr;
} else {
/*
* Copy all arguments to a local buffer for the unpacking.
@@ -324,8 +357,8 @@ print_op(int to, void *to_arg, int op, int size, Eterm* addr)
packed >>= BEAM_TIGHT_SHIFT;
break;
case '6': /* Shift 16 steps */
- *ap++ = packed & 0xffff;
- packed >>= 16;
+ *ap++ = packed & BEAM_LOOSE_MASK;
+ packed >>= BEAM_LOOSE_SHIFT;
break;
case 'p':
*sp++ = *--ap;
@@ -390,11 +423,11 @@ print_op(int to, void *to_arg, int op, int size, Eterm* addr)
case 'i': /* Tagged integer */
case 'c': /* Tagged constant */
case 'q': /* Tagged literal */
- erts_print(to, to_arg, "%T", *ap);
+ erts_print(to, to_arg, "%T", (Eterm) *ap);
ap++;
break;
case 'A':
- erts_print(to, to_arg, "%d", arityval(ap[0]));
+ erts_print(to, to_arg, "%d", arityval( (Eterm) ap[0]));
ap++;
break;
case 'd': /* Destination (x(0), x(N), y(N)) */
@@ -421,30 +454,36 @@ print_op(int to, void *to_arg, int op, int size, Eterm* addr)
ap++;
break;
case 'f': /* Destination label */
- erts_print(to, to_arg, "f(%X)", *ap);
- ap++;
+ {
+ BeamInstr* f = find_function_from_pc((BeamInstr *)*ap);
+ if (f+3 != (BeamInstr *) *ap) {
+ erts_print(to, to_arg, "f(" HEXF ")", *ap);
+ } else {
+ erts_print(to, to_arg, "%T:%T/%bpu", (Eterm) f[0], (Eterm) f[1], (Eterm) f[2]);
+ }
+ ap++;
+ }
break;
case 'p': /* Pointer (to label) */
{
- Eterm* f = find_function_from_pc((Eterm *)*ap);
-
- if (f+3 != (Eterm *) *ap) {
- erts_print(to, to_arg, "p(%X)", *ap);
+ BeamInstr* f = find_function_from_pc((BeamInstr *)*ap);
+ if (f+3 != (BeamInstr *) *ap) {
+ erts_print(to, to_arg, "p(" HEXF ")", *ap);
} else {
- erts_print(to, to_arg, "%T:%T/%bpu", f[0], f[1], f[2]);
+ erts_print(to, to_arg, "%T:%T/%bpu", (Eterm) f[0], (Eterm) f[1], (Eterm) f[2]);
}
ap++;
}
break;
case 'j': /* Pointer (to label) */
- erts_print(to, to_arg, "j(%X)", *ap);
+ erts_print(to, to_arg, "j(" HEXF ")", *ap);
ap++;
break;
case 'e': /* Export entry */
{
Export* ex = (Export *) *ap;
erts_print(to, to_arg,
- "%T:%T/%bpu", ex->code[0], ex->code[1], ex->code[2]);
+ "%T:%T/%bpu", (Eterm) ex->code[0], (Eterm) ex->code[1], (Uint) ex->code[2]);
ap++;
}
break;
@@ -467,7 +506,7 @@ print_op(int to, void *to_arg, int op, int size, Eterm* addr)
ap++;
break;
case 'P': /* Byte offset into tuple (see beam_load.c) */
- erts_print(to, to_arg, "%d", (*ap / sizeof(Eterm*)) - 1);
+ erts_print(to, to_arg, "%d", (*ap / sizeof(Eterm)) - 1);
ap++;
break;
case 'l': /* fr(N) */
@@ -494,7 +533,7 @@ print_op(int to, void *to_arg, int op, int size, Eterm* addr)
int n = ap[-1];
while (n > 0) {
- erts_print(to, to_arg, "%T f(%X) ", ap[0], ap[1]);
+ erts_print(to, to_arg, "%T f(" HEXF ") ", (Eterm) ap[0], ap[1]);
ap += 2;
size += 2;
n--;
@@ -505,7 +544,7 @@ print_op(int to, void *to_arg, int op, int size, Eterm* addr)
{
int n;
for (n = ap[-2]; n > 0; n--) {
- erts_print(to, to_arg, "f(%X) ", ap[0]);
+ erts_print(to, to_arg, "f(" HEXF ") ", ap[0]);
ap++;
size++;
}
@@ -513,11 +552,12 @@ print_op(int to, void *to_arg, int op, int size, Eterm* addr)
break;
case op_i_select_big_sf:
while (ap[0]) {
- int arity = thing_arityval(ap[0]);
- print_big(to, to_arg, ap);
- size += arity+1;
- ap += arity+1;
- erts_print(to, to_arg, " f(%X) ", ap[0]);
+ Eterm *bigp = (Eterm *) ap;
+ int arity = thing_arityval(*bigp);
+ print_big(to, to_arg, bigp);
+ size += TermWords(arity+1);
+ ap += TermWords(arity+1);
+ erts_print(to, to_arg, " f(" HEXF ") ", ap[0]);
ap++;
size++;
}
@@ -541,8 +581,8 @@ print_big(int to, void *to_arg, Eterm* addr)
erts_print(to, to_arg, "-#integer(%d) = {", i);
else
erts_print(to, to_arg, "#integer(%d) = {", i);
- erts_print(to, to_arg, "%d", BIG_DIGIT(addr, 0));
+ erts_print(to, to_arg, "0x%x", BIG_DIGIT(addr, 0));
for (k = 1; k < i; k++)
- erts_print(to, to_arg, ",%d", BIG_DIGIT(addr, k));
+ erts_print(to, to_arg, ",0x%x", BIG_DIGIT(addr, k));
erts_print(to, to_arg, "}");
}
diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c
index 2f7f48193d..834cc8df61 100644
--- a/erts/emulator/beam/beam_emu.c
+++ b/erts/emulator/beam/beam_emu.c
@@ -117,6 +117,7 @@ do { \
#endif
#define GET_BIF_ADDRESS(p) ((BifFunction) (((Export *) p)->code[4]))
+#define TermWords(t) (((t) / (sizeof(BeamInstr)/sizeof(Eterm))) + !!((t) % (sizeof(BeamInstr)/sizeof(Eterm))))
/*
@@ -138,8 +139,8 @@ do { \
#define VALID_INSTR(IP) (0 <= (int)(IP) && ((int)(IP) < (NUMBER_OF_OPCODES*2+10)))
#else
#define VALID_INSTR(IP) \
- ((Sint)LabelAddr(emulator_loop) <= (Sint)(IP) && \
- (Sint)(IP) < (Sint)LabelAddr(end_emulator_loop))
+ ((SWord)LabelAddr(emulator_loop) <= (SWord)(IP) && \
+ (SWord)(IP) < (SWord)LabelAddr(end_emulator_loop))
#endif /* NO_JUMP_TABLE */
#define SET_CP(p, ip) \
@@ -181,11 +182,11 @@ do { \
#define StoreBifResult(Dst, Result) \
do { \
- Eterm* stb_next; \
+ BeamInstr* stb_next; \
Eterm stb_reg; \
stb_reg = Arg(Dst); \
I += (Dst) + 2; \
- stb_next = (Eterm *) *I; \
+ stb_next = (BeamInstr *) *I; \
CHECK_TERM(Result); \
switch (beam_reg_tag(stb_reg)) { \
case R_REG_DEF: \
@@ -205,7 +206,7 @@ do { \
c_p->cp = 0; \
} while(0)
-#define RESTORE_CP(X) SET_CP(c_p, cp_val(*(X)))
+#define RESTORE_CP(X) SET_CP(c_p, (BeamInstr *) cp_val(*(X)))
#define ISCATCHEND(instr) ((Eterm *) *(instr) == OpCode(catch_end_y))
@@ -213,13 +214,13 @@ do { \
* Special Beam instructions.
*/
-Eterm beam_apply[2];
-Eterm beam_exit[1];
-Eterm beam_continue_exit[1];
+BeamInstr beam_apply[2];
+BeamInstr beam_exit[1];
+BeamInstr beam_continue_exit[1];
-Eterm* em_call_error_handler;
-Eterm* em_apply_bif;
-Eterm* em_call_traced_function;
+BeamInstr* em_call_error_handler;
+BeamInstr* em_apply_bif;
+BeamInstr* em_call_traced_function;
/* NOTE These should be the only variables containing trace instructions.
@@ -227,9 +228,9 @@ Eterm* em_call_traced_function;
** for the refering variable (one of these), and rouge references
** will most likely cause chaos.
*/
-Eterm beam_return_to_trace[1]; /* OpCode(i_return_to_trace) */
-Eterm beam_return_trace[1]; /* OpCode(i_return_trace) */
-Eterm beam_exception_trace[1]; /* UGLY also OpCode(i_return_trace) */
+BeamInstr beam_return_to_trace[1]; /* OpCode(i_return_to_trace) */
+BeamInstr beam_return_trace[1]; /* OpCode(i_return_trace) */
+BeamInstr beam_exception_trace[1]; /* UGLY also OpCode(i_return_trace) */
/*
* All Beam instructions in numerical order.
@@ -522,8 +523,8 @@ extern int count_instructions;
#define DispatchMacro() \
do { \
- Eterm* dis_next; \
- dis_next = (Eterm *) *I; \
+ BeamInstr* dis_next; \
+ dis_next = (BeamInstr *) *I; \
CHECK_ARGS(I); \
if (FCALLS > 0 || FCALLS > neg_o_reds) { \
FCALLS--; \
@@ -535,8 +536,8 @@ extern int count_instructions;
#define DispatchMacroFun() \
do { \
- Eterm* dis_next; \
- dis_next = (Eterm *) *I; \
+ BeamInstr* dis_next; \
+ dis_next = (BeamInstr *) *I; \
CHECK_ARGS(I); \
if (FCALLS > 0 || FCALLS > neg_o_reds) { \
FCALLS--; \
@@ -590,7 +591,7 @@ extern int count_instructions;
ASSERT(VALID_INSTR(*I)); \
Goto(*I)
-#define PreFetch(N, Dst) do { Dst = (Eterm *) *(I + N + 1); } while (0)
+#define PreFetch(N, Dst) do { Dst = (BeamInstr *) *(I + N + 1); } while (0)
#define NextPF(N, Dst) \
I += N + 1; \
ASSERT(VALID_INSTR(Dst)); \
@@ -644,7 +645,7 @@ extern int count_instructions;
#define DeallocateReturn(Deallocate) \
do { \
int words_to_pop = (Deallocate); \
- SET_I(cp_val(*E)); \
+ SET_I((BeamInstr *) cp_val(*E)); \
E = ADD_BYTE_OFFSET(E, words_to_pop); \
CHECK_TERM(r(0)); \
Goto(*I); \
@@ -657,19 +658,19 @@ extern int count_instructions;
#define MoveCall(Src, Dest, CallDest, Size) \
(Dest) = (Src); \
SET_CP(c_p, I+Size+1); \
- SET_I((Eterm *) CallDest); \
+ SET_I((BeamInstr *) CallDest); \
Dispatch();
#define MoveCallLast(Src, Dest, CallDest, Deallocate) \
(Dest) = (Src); \
RESTORE_CP(E); \
E = ADD_BYTE_OFFSET(E, (Deallocate)); \
- SET_I((Eterm *) CallDest); \
+ SET_I((BeamInstr *) CallDest); \
Dispatch();
#define MoveCallOnly(Src, Dest, CallDest) \
(Dest) = (Src); \
- SET_I((Eterm *) CallDest); \
+ SET_I((BeamInstr *) CallDest); \
Dispatch();
#define GetList(Src, H, T) do { \
@@ -677,47 +678,48 @@ extern int count_instructions;
H = CAR(tmp_ptr); \
T = CDR(tmp_ptr); } while (0)
-#define GetTupleElement(Src, Element, Dest) \
- do { \
- tmp_arg1 = (Eterm) (((unsigned char *) tuple_val(Src)) + (Element)); \
- (Dest) = (*(Eterm *)tmp_arg1); \
+#define GetTupleElement(Src, Element, Dest) \
+ do { \
+ tmp_arg1 = (Eterm) COMPRESS_POINTER(((unsigned char *) tuple_val(Src)) + \
+ (Element)); \
+ (Dest) = (*(Eterm *) EXPAND_POINTER(tmp_arg1)); \
} while (0)
-#define ExtractNextElement(Dest) \
- tmp_arg1 += sizeof(Eterm); \
- (Dest) = (* (Eterm *) (((unsigned char *) tmp_arg1)))
+#define ExtractNextElement(Dest) \
+ tmp_arg1 += sizeof(Eterm); \
+ (Dest) = (* (Eterm *) (((unsigned char *) EXPAND_POINTER(tmp_arg1))))
-#define ExtractNextElement2(Dest) \
- do { \
- Eterm* ene_dstp = &(Dest); \
- ene_dstp[0] = ((Eterm *) tmp_arg1)[1]; \
- ene_dstp[1] = ((Eterm *) tmp_arg1)[2]; \
- tmp_arg1 += sizeof(Eterm) + sizeof(Eterm); \
+#define ExtractNextElement2(Dest) \
+ do { \
+ Eterm* ene_dstp = &(Dest); \
+ ene_dstp[0] = ((Eterm *) EXPAND_POINTER(tmp_arg1))[1]; \
+ ene_dstp[1] = ((Eterm *) EXPAND_POINTER(tmp_arg1))[2]; \
+ tmp_arg1 += sizeof(Eterm) + sizeof(Eterm); \
} while (0)
#define ExtractNextElement3(Dest) \
do { \
Eterm* ene_dstp = &(Dest); \
- ene_dstp[0] = ((Eterm *) tmp_arg1)[1]; \
- ene_dstp[1] = ((Eterm *) tmp_arg1)[2]; \
- ene_dstp[2] = ((Eterm *) tmp_arg1)[3]; \
+ ene_dstp[0] = ((Eterm *) EXPAND_POINTER(tmp_arg1))[1]; \
+ ene_dstp[1] = ((Eterm *) EXPAND_POINTER(tmp_arg1))[2]; \
+ ene_dstp[2] = ((Eterm *) EXPAND_POINTER(tmp_arg1))[3]; \
tmp_arg1 += 3*sizeof(Eterm); \
} while (0)
#define ExtractNextElement4(Dest) \
do { \
Eterm* ene_dstp = &(Dest); \
- ene_dstp[0] = ((Eterm *) tmp_arg1)[1]; \
- ene_dstp[1] = ((Eterm *) tmp_arg1)[2]; \
- ene_dstp[2] = ((Eterm *) tmp_arg1)[3]; \
- ene_dstp[3] = ((Eterm *) tmp_arg1)[4]; \
+ ene_dstp[0] = ((Eterm *) EXPAND_POINTER(tmp_arg1))[1]; \
+ ene_dstp[1] = ((Eterm *) EXPAND_POINTER(tmp_arg1))[2]; \
+ ene_dstp[2] = ((Eterm *) EXPAND_POINTER(tmp_arg1))[3]; \
+ ene_dstp[3] = ((Eterm *) EXPAND_POINTER(tmp_arg1))[4]; \
tmp_arg1 += 4*sizeof(Eterm); \
} while (0)
#define ExtractElement(Element, Dest) \
do { \
tmp_arg1 += (Element); \
- (Dest) = (* (Eterm *) tmp_arg1); \
+ (Dest) = (* (Eterm *) EXPAND_POINTER(tmp_arg1)); \
} while (0)
#define PutTuple(Arity, Src, Dest) \
@@ -759,8 +761,13 @@ extern int count_instructions;
#define IsTuple(X, Action) if (is_not_tuple(X)) Action
-#define IsArity(Pointer, Arity, Fail) \
- if (*(Eterm *)(tmp_arg1 = (Eterm)tuple_val(Pointer)) != (Arity)) { Fail; }
+#define IsArity(Pointer, Arity, Fail) \
+ if (*(Eterm *) \
+ EXPAND_POINTER(tmp_arg1 = (Eterm) \
+ COMPRESS_POINTER(tuple_val(Pointer))) != (Arity)) \
+ { \
+ Fail; \
+ }
#define IsFunction(X, Action) \
do { \
@@ -776,11 +783,14 @@ extern int count_instructions;
} \
} while (0)
-#define IsTupleOfArity(Src, Arity, Fail) \
- do { \
- if (is_not_tuple(Src) || *(Eterm *)(tmp_arg1 = (Eterm) tuple_val(Src)) != Arity) { \
- Fail; \
- } \
+#define IsTupleOfArity(Src, Arity, Fail) \
+ do { \
+ if (is_not_tuple(Src) || \
+ *(Eterm *) \
+ EXPAND_POINTER(tmp_arg1 = \
+ (Eterm) COMPRESS_POINTER(tuple_val(Src))) != Arity) { \
+ Fail; \
+ } \
} while (0)
#define IsBoolean(X, Fail) if ((X) != am_true && (X) != am_false) { Fail; }
@@ -791,7 +801,7 @@ extern int count_instructions;
#define IsBitstring(Src, Fail) \
if (is_not_binary(Src)) { Fail; }
-#ifdef ARCH_64
+#if defined(ARCH_64) && !HALFWORD_HEAP
#define BsSafeMul(A, B, Fail, Target) \
do { Uint64 _res = (A) * (B); \
if (_res / B != A) { Fail; } \
@@ -974,23 +984,23 @@ extern int count_instructions;
#define IsRef(Src, Fail) if (is_not_ref(Src)) { Fail; }
static BifFunction translate_gc_bif(void* gcf);
-static Eterm* handle_error(Process* c_p, Eterm* pc, Eterm* reg, BifFunction bf);
-static Eterm* next_catch(Process* c_p, Eterm *reg);
+static BeamInstr* handle_error(Process* c_p, BeamInstr* pc, Eterm* reg, BifFunction bf);
+static BeamInstr* next_catch(Process* c_p, Eterm *reg);
static void terminate_proc(Process* c_p, Eterm Value);
static Eterm add_stacktrace(Process* c_p, Eterm Value, Eterm exc);
-static void save_stacktrace(Process* c_p, Eterm* pc, Eterm* reg,
+static void save_stacktrace(Process* c_p, BeamInstr* pc, Eterm* reg,
BifFunction bf, Eterm args);
static struct StackTrace * get_trace_from_exc(Eterm exc);
static Eterm make_arglist(Process* c_p, Eterm* reg, int a);
-static Eterm call_error_handler(Process* p, Eterm* ip, Eterm* reg);
-static Eterm call_breakpoint_handler(Process* p, Eterm* fi, Eterm* reg);
-static Uint* fixed_apply(Process* p, Eterm* reg, Uint arity);
-static Eterm* apply(Process* p, Eterm module, Eterm function,
+static Eterm call_error_handler(Process* p, BeamInstr* ip, Eterm* reg);
+static Eterm call_breakpoint_handler(Process* p, BeamInstr* fi, Eterm* reg);
+static BeamInstr* fixed_apply(Process* p, Eterm* reg, Uint arity);
+static BeamInstr* apply(Process* p, Eterm module, Eterm function,
Eterm args, Eterm* reg);
static int hibernate(Process* c_p, Eterm module, Eterm function,
Eterm args, Eterm* reg);
-static Eterm* call_fun(Process* p, int arity, Eterm* reg, Eterm args);
-static Eterm* apply_fun(Process* p, Eterm fun, Eterm args, Eterm* reg);
+static BeamInstr* call_fun(Process* p, int arity, Eterm* reg, Eterm args);
+static BeamInstr* apply_fun(Process* p, Eterm fun, Eterm args, Eterm* reg);
static Eterm new_fun(Process* p, Eterm* reg, ErlFunEntry* fe, int num_free);
#if defined(_OSE_) || defined(VXWORKS)
@@ -1078,7 +1088,7 @@ void process_main(void)
/*
* Pointer to next threaded instruction.
*/
- register Eterm *I REG_I = NULL;
+ register BeamInstr *I REG_I = NULL;
/* Number of reductions left. This function
* returns to the scheduler when FCALLS reaches zero.
@@ -1090,9 +1100,14 @@ void process_main(void)
*/
register Eterm tmp_arg1 REG_tmp_arg1 = NIL;
register Eterm tmp_arg2 REG_tmp_arg2 = NIL;
- Eterm tmp_big[2]; /* Temporary buffer for small bignums. */
+#if HEAP_ON_C_STACK
+ Eterm tmp_big[2]; /* Temporary buffer for small bignums if HEAP_ON_C_STACK. */
+#else
+ Eterm *tmp_big; /* Temporary buffer for small bignums if !HEAP_ON_C_STACK. */
+#endif
#ifndef ERTS_SMP
+#if !HALFWORD_HEAP
static Eterm save_reg[ERTS_X_REGS_ALLOCATED];
/* X registers -- not used directly, but
* through 'reg', because using it directly
@@ -1100,7 +1115,7 @@ void process_main(void)
* while using it through reg needs only
* one.
*/
-
+#endif
/*
* Floating point registers.
*/
@@ -1141,13 +1156,17 @@ void process_main(void)
* Note: c_p->arity must be set to reflect the number of useful terms in
* c_p->arg_reg before calling the scheduler.
*/
-
if (!init_done) {
init_done = 1;
goto init_emulator;
}
#ifndef ERTS_SMP
+#if !HALFWORD_HEAP
reg = save_reg; /* XXX: probably wastes a register on x86 */
+#else
+ /* Registers need to be heap allocated (correct memory range) for tracing to work */
+ reg = erts_alloc(ERTS_ALC_T_BEAM_REGISTER, ERTS_X_REGS_ALLOCATED * sizeof(Eterm));
+#endif
#endif
c_p = NULL;
reds_used = 0;
@@ -1168,11 +1187,14 @@ void process_main(void)
reg = c_p->scheduler_data->save_reg;
freg = c_p->scheduler_data->freg;
#endif
+#if !HEAP_ON_C_STACK
+ tmp_big = ERTS_PROC_GET_SCHDATA(c_p)->beam_emu_tmp_heap;
+#endif
ERL_BITS_RELOAD_STATEP(c_p);
{
int reds;
Eterm* argp;
- Eterm* next;
+ BeamInstr *next;
int i;
argp = c_p->arg_reg;
@@ -1199,7 +1221,7 @@ void process_main(void)
FCALLS = REDS_IN(c_p) = reds;
}
- next = (Eterm *) *I;
+ next = (BeamInstr *) *I;
r(0) = c_p->arg_reg[0];
#ifdef HARDDEBUG
if (c_p->arity > 0) {
@@ -1291,7 +1313,7 @@ void process_main(void)
}
/* FALL THROUGH */
OpCase(i_call_only_f): {
- SET_I((Eterm *) Arg(0));
+ SET_I((BeamInstr *) Arg(0));
Dispatch();
}
@@ -1302,7 +1324,7 @@ void process_main(void)
OpCase(i_call_last_fP): {
RESTORE_CP(E);
E = ADD_BYTE_OFFSET(E, Arg(1));
- SET_I((Eterm *) Arg(0));
+ SET_I((BeamInstr *) Arg(0));
Dispatch();
}
@@ -1313,7 +1335,7 @@ void process_main(void)
/* FALL THROUGH */
OpCase(i_call_f): {
SET_CP(c_p, I+2);
- SET_I((Eterm *) Arg(0));
+ SET_I((BeamInstr *) Arg(0));
Dispatch();
}
@@ -1349,7 +1371,7 @@ void process_main(void)
Dispatchx();
OpCase(init_y): {
- Eterm* next;
+ BeamInstr *next;
PreFetch(1, next);
make_blank(yb(Arg(0)));
@@ -1357,7 +1379,7 @@ void process_main(void)
}
OpCase(i_trim_I): {
- Eterm* next;
+ BeamInstr *next;
Uint words;
Uint cp;
@@ -1383,7 +1405,7 @@ void process_main(void)
}
OpCase(test_heap_1_put_list_Iy): {
- Eterm* next;
+ BeamInstr *next;
PreFetch(2, next);
TestHeap(Arg(0), 1);
@@ -1414,7 +1436,7 @@ void process_main(void)
*/
OpCase(send): {
- Eterm* next;
+ BeamInstr *next;
Eterm result;
PRE_BIF_SWAPOUT(c_p);
@@ -1429,7 +1451,7 @@ void process_main(void)
NextPF(0, next);
} else if (c_p->freason == TRAP) {
SET_CP(c_p, I+1);
- SET_I((Eterm *) c_p->def_arg_reg[3]);
+ SET_I(*((BeamInstr **) (BeamInstr) ((c_p)->def_arg_reg + 3)));
SWAPIN;
r(0) = c_p->def_arg_reg[0];
x(1) = c_p->def_arg_reg[1];
@@ -1555,7 +1577,7 @@ void process_main(void)
*/
OpCase(i_loop_rec_fr):
{
- Eterm* next;
+ BeamInstr *next;
ErlMessage* msgp;
loop_rec__:
@@ -1579,7 +1601,7 @@ void process_main(void)
erts_smp_proc_unlock(c_p, ERTS_PROC_LOCKS_MSG_RECEIVE);
else {
#endif
- SET_I((Eterm *) Arg(0));
+ SET_I((BeamInstr *) Arg(0));
Goto(*I); /* Jump to a wait or wait_timeout instruction */
#ifdef ERTS_SMP
}
@@ -1615,7 +1637,7 @@ void process_main(void)
* Remove a (matched) message from the message queue.
*/
OpCase(remove_message): {
- Eterm* next;
+ BeamInstr *next;
ErlMessage* msgp;
PROCESS_MAIN_CHK_LOCKS(c_p);
@@ -1660,7 +1682,7 @@ void process_main(void)
* message didn't match), then jump to the loop_rec instruction.
*/
OpCase(loop_rec_end_f): {
- SET_I((Eterm *) Arg(0));
+ SET_I((BeamInstr *) Arg(0));
SAVE_MESSAGE(c_p);
goto loop_rec__;
}
@@ -1690,12 +1712,12 @@ void process_main(void)
}
GetArg1(1, timeout_value);
if (timeout_value != make_small(0)) {
-#if !defined(ARCH_64)
+#if !defined(ARCH_64) || HALFWORD_HEAP
Uint time_val;
#endif
if (is_small(timeout_value) && signed_val(timeout_value) > 0 &&
-#if defined(ARCH_64)
+#if defined(ARCH_64) && !HALFWORD_HEAP
((unsigned_val(timeout_value) >> 32) == 0)
#else
1
@@ -1706,14 +1728,16 @@ void process_main(void)
* c_p->def_arg_reg[0]. Note that it is safe to use this
* location because there are no living x registers in
* a receive statement.
+ * Note that for the halfword emulator, the two first elements
+ * of the array are used.
*/
- c_p->def_arg_reg[0] = (Eterm) (I+3);
+ *((BeamInstr **) (UWord) c_p->def_arg_reg) = I+3;
set_timer(c_p, unsigned_val(timeout_value));
} else if (timeout_value == am_infinity) {
c_p->flags |= F_TIMO;
-#if !defined(ARCH_64)
+#if !defined(ARCH_64) || HALFWORD_HEAP
} else if (term_to_Uint(timeout_value, &time_val)) {
- c_p->def_arg_reg[0] = (Eterm) (I+3);
+ *((BeamInstr **) (UWord) c_p->def_arg_reg) = I+3;
set_timer(c_p, time_val);
#endif
} else { /* Wrong time */
@@ -1742,7 +1766,7 @@ void process_main(void)
wait2: {
ASSERT(!ERTS_PROC_IS_EXITING(c_p));
- c_p->i = (Eterm *) Arg(0); /* L1 */
+ c_p->i = (BeamInstr *) Arg(0); /* L1 */
SWAPOUT;
c_p->arity = 0;
c_p->status = P_WAITING;
@@ -1770,7 +1794,7 @@ void process_main(void)
* we must test the F_INSLPQUEUE flag as well as the F_TIMO flag.
*/
if ((c_p->flags & (F_INSLPQUEUE | F_TIMO)) == 0) {
- c_p->def_arg_reg[0] = (Eterm) (I+3);
+ *((BeamInstr **) (UWord) c_p->def_arg_reg) = I+3;
set_timer(c_p, Arg(1));
}
goto wait2;
@@ -1785,7 +1809,7 @@ void process_main(void)
}
OpCase(timeout): {
- Eterm* next;
+ BeamInstr *next;
PreFetch(0, next);
if (IS_TRACED_FL(c_p, F_TRACE_RECEIVE)) {
@@ -1805,8 +1829,8 @@ void process_main(void)
do_binary_search:
{
struct Pairs {
- Eterm val;
- Eterm* addr;
+ BeamInstr val;
+ BeamInstr* addr;
};
struct Pairs* low;
struct Pairs* high;
@@ -1846,7 +1870,7 @@ void process_main(void)
Goto(*I);
}
}
- SET_I((Eterm *) Arg(1));
+ SET_I((BeamInstr *) Arg(1));
Goto(*I);
}
@@ -1858,11 +1882,11 @@ void process_main(void)
if (is_small(index)) {
index = signed_val(index);
if (index < Arg(2)) {
- SET_I((Eterm *) (&Arg(3))[index]);
+ SET_I((BeamInstr *) (&Arg(3))[index]);
Goto(*I);
}
}
- SET_I((Eterm *) Arg(1));
+ SET_I((BeamInstr *) Arg(1));
Goto(*I);
}
@@ -1874,11 +1898,11 @@ void process_main(void)
if (is_small(index)) {
index = (Uint) (signed_val(index) - Arg(3));
if (index < Arg(2)) {
- SET_I((Eterm *) (&Arg(4))[index]);
+ SET_I((BeamInstr *) (&Arg(4))[index]);
Goto(*I);
}
}
- SET_I((Eterm *) Arg(1));
+ SET_I((BeamInstr *) Arg(1));
Goto(*I);
}
@@ -1915,7 +1939,7 @@ void process_main(void)
if (is_value(result)) {
StoreBifResult(3, result);
}
- SET_I((Eterm *) Arg(0));
+ SET_I((BeamInstr *) Arg(0));
Goto(*I);
}
@@ -1955,7 +1979,7 @@ void process_main(void)
GcBifFunction bf;
Eterm arg;
Eterm result;
- Uint live = Arg(3);
+ Uint live = (Uint) Arg(3);
GetArg1(2, arg);
reg[0] = r(0);
@@ -1976,7 +2000,7 @@ void process_main(void)
StoreBifResult(4, result);
}
if (Arg(0) != 0) {
- SET_I((Eterm *) Arg(0));
+ SET_I((BeamInstr *) Arg(0));
Goto(*I);
}
reg[0] = arg;
@@ -2004,7 +2028,7 @@ void process_main(void)
if (is_value(result)) {
StoreBifResult(2, result);
}
- SET_I((Eterm *) Arg(0));
+ SET_I((BeamInstr *) Arg(0));
Goto(*I);
}
@@ -2040,7 +2064,7 @@ void process_main(void)
*/
OpCase(call_bif0_e):
{
- Eterm (*bf)(Process*, Uint*) = GET_BIF_ADDRESS(Arg(0));
+ Eterm (*bf)(Process*, BeamInstr*) = GET_BIF_ADDRESS(Arg(0));
PRE_BIF_SWAPOUT(c_p);
c_p->fcalls = FCALLS - 1;
@@ -2073,9 +2097,9 @@ void process_main(void)
OpCase(call_bif1_e):
{
- Eterm (*bf)(Process*, Eterm, Uint*) = GET_BIF_ADDRESS(Arg(0));
+ Eterm (*bf)(Process*, Eterm, BeamInstr*) = GET_BIF_ADDRESS(Arg(0));
Eterm result;
- Eterm* next;
+ BeamInstr *next;
c_p->fcalls = FCALLS - 1;
if (FCALLS <= 0) {
@@ -2108,9 +2132,9 @@ void process_main(void)
OpCase(call_bif2_e):
{
- Eterm (*bf)(Process*, Eterm, Eterm, Uint*) = GET_BIF_ADDRESS(Arg(0));
+ Eterm (*bf)(Process*, Eterm, Eterm, BeamInstr*) = GET_BIF_ADDRESS(Arg(0));
Eterm result;
- Eterm* next;
+ BeamInstr *next;
PRE_BIF_SWAPOUT(c_p);
c_p->fcalls = FCALLS - 1;
@@ -2145,9 +2169,9 @@ void process_main(void)
OpCase(call_bif3_e):
{
- Eterm (*bf)(Process*, Eterm, Eterm, Eterm, Uint*) = GET_BIF_ADDRESS(Arg(0));
+ Eterm (*bf)(Process*, Eterm, Eterm, Eterm, BeamInstr*) = GET_BIF_ADDRESS(Arg(0));
Eterm result;
- Eterm* next;
+ BeamInstr *next;
PRE_BIF_SWAPOUT(c_p);
c_p->fcalls = FCALLS - 1;
@@ -2168,7 +2192,7 @@ void process_main(void)
} else if (c_p->freason == TRAP) {
call_bif_trap3:
SET_CP(c_p, I+2);
- SET_I((Eterm *)c_p->def_arg_reg[3]);
+ SET_I(*((BeamInstr **) (UWord) ((c_p)->def_arg_reg + 3)));
SWAPIN;
r(0) = c_p->def_arg_reg[0];
x(1) = c_p->def_arg_reg[1];
@@ -2276,7 +2300,7 @@ void process_main(void)
lb_Cl_error: {
if (Arg(0) != 0) {
OpCase(jump_f): {
- SET_I((Eterm *) Arg(0));
+ SET_I((BeamInstr *) Arg(0));
Goto(*I);
}
}
@@ -2468,7 +2492,7 @@ void process_main(void)
goto lb_Cl_error;
OpCase(i_apply): {
- Eterm* next;
+ BeamInstr *next;
SWAPOUT;
next = apply(c_p, r(0), x(1), x(2), reg);
SWAPIN;
@@ -2483,13 +2507,13 @@ void process_main(void)
}
OpCase(i_apply_last_P): {
- Eterm* next;
+ BeamInstr *next;
SWAPOUT;
next = apply(c_p, r(0), x(1), x(2), reg);
SWAPIN;
if (next != NULL) {
r(0) = reg[0];
- SET_CP(c_p, (Eterm *) E[0]);
+ SET_CP(c_p, (BeamInstr *) EXPAND_POINTER(E[0]));
E = ADD_BYTE_OFFSET(E, Arg(0));
SET_I(next);
Dispatch();
@@ -2499,7 +2523,7 @@ void process_main(void)
}
OpCase(i_apply_only): {
- Eterm* next;
+ BeamInstr *next;
SWAPOUT;
next = apply(c_p, r(0), x(1), x(2), reg);
SWAPIN;
@@ -2513,7 +2537,7 @@ void process_main(void)
}
OpCase(apply_I): {
- Eterm* next;
+ BeamInstr *next;
reg[0] = r(0);
SWAPOUT;
@@ -2530,7 +2554,7 @@ void process_main(void)
}
OpCase(apply_last_IP): {
- Eterm* next;
+ BeamInstr *next;
reg[0] = r(0);
SWAPOUT;
@@ -2538,7 +2562,7 @@ void process_main(void)
SWAPIN;
if (next != NULL) {
r(0) = reg[0];
- SET_CP(c_p, (Eterm *) E[0]);
+ SET_CP(c_p, (BeamInstr *) EXPAND_POINTER(E[0]));
E = ADD_BYTE_OFFSET(E, Arg(1));
SET_I(next);
Dispatch();
@@ -2548,7 +2572,7 @@ void process_main(void)
}
OpCase(i_apply_fun): {
- Eterm* next;
+ BeamInstr *next;
SWAPOUT;
next = apply_fun(c_p, r(0), x(1), reg);
@@ -2563,14 +2587,14 @@ void process_main(void)
}
OpCase(i_apply_fun_last_P): {
- Eterm* next;
+ BeamInstr *next;
SWAPOUT;
next = apply_fun(c_p, r(0), x(1), reg);
SWAPIN;
if (next != NULL) {
r(0) = reg[0];
- SET_CP(c_p, (Eterm *) E[0]);
+ SET_CP(c_p, (BeamInstr *) EXPAND_POINTER(E[0]));
E = ADD_BYTE_OFFSET(E, Arg(0));
SET_I(next);
Dispatchfun();
@@ -2579,7 +2603,7 @@ void process_main(void)
}
OpCase(i_apply_fun_only): {
- Eterm* next;
+ BeamInstr *next;
SWAPOUT;
next = apply_fun(c_p, r(0), x(1), reg);
@@ -2593,10 +2617,11 @@ void process_main(void)
}
OpCase(i_call_fun_I): {
- Eterm* next;
+ BeamInstr *next;
SWAPOUT;
reg[0] = r(0);
+
next = call_fun(c_p, Arg(0), reg, THE_NON_VALUE);
SWAPIN;
if (next != NULL) {
@@ -2609,7 +2634,7 @@ void process_main(void)
}
OpCase(i_call_fun_last_IP): {
- Eterm* next;
+ BeamInstr *next;
SWAPOUT;
reg[0] = r(0);
@@ -2617,7 +2642,7 @@ void process_main(void)
SWAPIN;
if (next != NULL) {
r(0) = reg[0];
- SET_CP(c_p, (Eterm *) E[0]);
+ SET_CP(c_p, (BeamInstr *) EXPAND_POINTER(E[0]));
E = ADD_BYTE_OFFSET(E, Arg(1));
SET_I(next);
Dispatchfun();
@@ -2722,7 +2747,7 @@ void process_main(void)
tmp_arg1 = *tuple_val(tmp_arg1);
goto do_binary_search;
}
- SET_I((Eterm *) Arg(1));
+ SET_I((BeamInstr *) Arg(1));
Goto(*I);
}
@@ -2748,16 +2773,18 @@ void process_main(void)
given = big_val(tmp_arg1);
given_arity = given[0];
given_size = thing_arityval(given_arity);
- bigp = &Arg(2);
+ bigp = (Eterm *) &Arg(2);
while ((arity = bigp[0]) > given_arity) {
- bigp += thing_arityval(arity) + 2;
+ bigp += (TermWords(thing_arityval(arity) + 1) + 1) * (sizeof(BeamInstr)/sizeof(Eterm));
}
while (bigp[0] == given_arity) {
if (memcmp(bigp+1, given+1, sizeof(Eterm)*given_size) == 0) {
- SET_I((Eterm *) bigp[given_size+1]);
+ BeamInstr *tmp =
+ ((BeamInstr *) (UWord) bigp) + TermWords(given_size + 1);
+ SET_I((BeamInstr *) *tmp);
Goto(*I);
}
- bigp += thing_arityval(arity) + 2;
+ bigp += (TermWords(thing_arityval(arity) + 1) + 1) * (sizeof(BeamInstr)/sizeof(Eterm));
}
}
@@ -2765,18 +2792,18 @@ void process_main(void)
* Failed.
*/
- SET_I((Eterm *) Arg(1));
+ SET_I((BeamInstr *) Arg(1));
Goto(*I);
}
-#ifdef ARCH_64
+#if defined(ARCH_64) && !HALFWORD_HEAP
OpCase(i_select_float_sfI):
{
Uint f;
int n;
struct ValLabel {
Uint f;
- Eterm* addr;
+ BeamInstr* addr;
};
struct ValLabel* ptr;
@@ -2804,7 +2831,7 @@ void process_main(void)
struct ValLabel {
Uint fpart1;
Uint fpart2;
- Eterm* addr;
+ BeamInstr* addr;
};
struct ValLabel* ptr;
@@ -2822,7 +2849,7 @@ void process_main(void)
}
ptr++;
}
- SET_I((Eterm *) Arg(1));
+ SET_I((BeamInstr *) Arg(1));
Goto(*I);
}
#endif
@@ -2830,7 +2857,7 @@ void process_main(void)
OpCase(set_tuple_element_sdP): {
Eterm element;
Eterm tuple;
- Eterm* next;
+ BeamInstr *next;
Eterm* p;
PreFetch(3, next);
@@ -3025,7 +3052,7 @@ void process_main(void)
switch (tmp_arg2) {
case 3:
{
- Eterm (*bf)(Process*, Eterm, Eterm, Eterm, Uint*) = vbf;
+ Eterm (*bf)(Process*, Eterm, Eterm, Eterm, BeamInstr*) = vbf;
ASSERT(!ERTS_PROC_IS_EXITING(c_p));
tmp_arg1 = (*bf)(c_p, r(0), x(1), x(2), I);
ASSERT(!ERTS_PROC_IS_EXITING(c_p) || is_non_value(tmp_arg1));
@@ -3034,7 +3061,7 @@ void process_main(void)
break;
case 2:
{
- Eterm (*bf)(Process*, Eterm, Eterm, Uint*) = vbf;
+ Eterm (*bf)(Process*, Eterm, Eterm, BeamInstr*) = vbf;
ASSERT(!ERTS_PROC_IS_EXITING(c_p));
tmp_arg1 = (*bf)(c_p, r(0), x(1), I);
ASSERT(!ERTS_PROC_IS_EXITING(c_p) || is_non_value(tmp_arg1));
@@ -3043,7 +3070,7 @@ void process_main(void)
break;
case 1:
{
- Eterm (*bf)(Process*, Eterm, Uint*) = vbf;
+ Eterm (*bf)(Process*, Eterm, BeamInstr*) = vbf;
ASSERT(!ERTS_PROC_IS_EXITING(c_p));
tmp_arg1 = (*bf)(c_p, r(0), I);
ASSERT(!ERTS_PROC_IS_EXITING(c_p) || is_non_value(tmp_arg1));
@@ -3052,7 +3079,7 @@ void process_main(void)
break;
case 0:
{
- Eterm (*bf)(Process*, Uint*) = vbf;
+ Eterm (*bf)(Process*, BeamInstr*) = vbf;
ASSERT(!ERTS_PROC_IS_EXITING(c_p));
tmp_arg1 = (*bf)(c_p, I);
ASSERT(!ERTS_PROC_IS_EXITING(c_p) || is_non_value(tmp_arg1));
@@ -3076,7 +3103,7 @@ apply_bif_or_nif_epilogue:
SET_I(c_p->cp);
Goto(*I);
} else if (c_p->freason == TRAP) {
- SET_I((Eterm *)c_p->def_arg_reg[3]);
+ SET_I(*((BeamInstr **) (UWord) ((c_p)->def_arg_reg + 3)));
r(0) = c_p->def_arg_reg[0];
x(1) = c_p->def_arg_reg[1];
x(2) = c_p->def_arg_reg[2];
@@ -3534,7 +3561,7 @@ apply_bif_or_nif_epilogue:
OpCase(bs_put_string_II):
{
- Eterm* next;
+ BeamInstr *next;
PreFetch(2, next);
erts_new_bs_put_string(ERL_BITS_ARGS_2((byte *) Arg(1), Arg(0)));
NextPF(2, next);
@@ -3705,7 +3732,7 @@ apply_bif_or_nif_epilogue:
{
Eterm header;
- Eterm* next;
+ BeamInstr *next;
Uint slots;
OpCase(i_bs_start_match2_rfIId): {
@@ -3771,7 +3798,7 @@ apply_bif_or_nif_epilogue:
}
OpCase(bs_test_zero_tail2_fr): {
- Eterm* next;
+ BeamInstr *next;
ErlBinMatchBuffer *_mb;
PreFetch(1, next);
@@ -3783,7 +3810,7 @@ apply_bif_or_nif_epilogue:
}
OpCase(bs_test_zero_tail2_fx): {
- Eterm* next;
+ BeamInstr *next;
ErlBinMatchBuffer *_mb;
PreFetch(2, next);
@@ -3795,7 +3822,7 @@ apply_bif_or_nif_epilogue:
}
OpCase(bs_test_tail_imm2_frI): {
- Eterm* next;
+ BeamInstr *next;
ErlBinMatchBuffer *_mb;
PreFetch(2, next);
_mb = ms_matchbuffer(r(0));
@@ -3805,7 +3832,7 @@ apply_bif_or_nif_epilogue:
NextPF(2, next);
}
OpCase(bs_test_tail_imm2_fxI): {
- Eterm* next;
+ BeamInstr *next;
ErlBinMatchBuffer *_mb;
PreFetch(3, next);
_mb = ms_matchbuffer(xb(Arg(1)));
@@ -3816,7 +3843,7 @@ apply_bif_or_nif_epilogue:
}
OpCase(bs_test_unit_frI): {
- Eterm* next;
+ BeamInstr *next;
ErlBinMatchBuffer *_mb;
PreFetch(2, next);
_mb = ms_matchbuffer(r(0));
@@ -3826,7 +3853,7 @@ apply_bif_or_nif_epilogue:
NextPF(2, next);
}
OpCase(bs_test_unit_fxI): {
- Eterm* next;
+ BeamInstr *next;
ErlBinMatchBuffer *_mb;
PreFetch(3, next);
_mb = ms_matchbuffer(xb(Arg(1)));
@@ -3837,7 +3864,7 @@ apply_bif_or_nif_epilogue:
}
OpCase(bs_test_unit8_fr): {
- Eterm* next;
+ BeamInstr *next;
ErlBinMatchBuffer *_mb;
PreFetch(1, next);
_mb = ms_matchbuffer(r(0));
@@ -3847,7 +3874,7 @@ apply_bif_or_nif_epilogue:
NextPF(1, next);
}
OpCase(bs_test_unit8_fx): {
- Eterm* next;
+ BeamInstr *next;
ErlBinMatchBuffer *_mb;
PreFetch(2, next);
_mb = ms_matchbuffer(xb(Arg(1)));
@@ -3931,11 +3958,11 @@ apply_bif_or_nif_epilogue:
_integer = get_int32(_mb->base + _mb->offset/8);
}
_mb->offset += 32;
-#ifndef ARCH_64
+#if !defined(ARCH_64) || HALFWORD_HEAP
if (IS_USMALL(0, _integer)) {
#endif
_result = make_small(_integer);
-#ifndef ARCH_64
+#if !defined(ARCH_64) || HALFWORD_HEAP
} else {
TestHeap(BIG_UINT_HEAP_SIZE, Arg(1));
_result = uint_to_big((Uint) _integer, HTOP);
@@ -4172,7 +4199,7 @@ apply_bif_or_nif_epilogue:
do_bs_match_string:
{
- Eterm* next;
+ BeamInstr *next;
byte* bytes;
Uint bits;
ErlBinMatchBuffer* mb;
@@ -4199,7 +4226,7 @@ apply_bif_or_nif_epilogue:
}
OpCase(i_bs_save2_rI): {
- Eterm* next;
+ BeamInstr *next;
ErlBinMatchState *_ms;
PreFetch(1, next);
_ms = (ErlBinMatchState*) boxed_val((Eterm) r(0));
@@ -4207,7 +4234,7 @@ apply_bif_or_nif_epilogue:
NextPF(1, next);
}
OpCase(i_bs_save2_xI): {
- Eterm* next;
+ BeamInstr *next;
ErlBinMatchState *_ms;
PreFetch(2, next);
_ms = (ErlBinMatchState*) boxed_val((Eterm) xb(Arg(0)));
@@ -4216,7 +4243,7 @@ apply_bif_or_nif_epilogue:
}
OpCase(i_bs_restore2_rI): {
- Eterm* next;
+ BeamInstr *next;
ErlBinMatchState *_ms;
PreFetch(1, next);
_ms = (ErlBinMatchState*) boxed_val((Eterm) r(0));
@@ -4224,7 +4251,7 @@ apply_bif_or_nif_epilogue:
NextPF(1, next);
}
OpCase(i_bs_restore2_xI): {
- Eterm* next;
+ BeamInstr *next;
ErlBinMatchState *_ms;
PreFetch(2, next);
_ms = (ErlBinMatchState*) boxed_val((Eterm) xb(Arg(0)));
@@ -4241,7 +4268,7 @@ apply_bif_or_nif_epilogue:
* deallocate not followed by a return, and that should work.
*/
OpCase(deallocate_I): {
- Eterm* next;
+ BeamInstr *next;
PreFetch(1, next);
D(Arg(0));
@@ -4264,7 +4291,7 @@ apply_bif_or_nif_epilogue:
*/
OpCase(call_traced_function): {
if (IS_TRACED_FL(c_p, F_TRACE_CALLS)) {
- unsigned offset = offsetof(Export, code) + 3*sizeof(Eterm);
+ unsigned offset = offsetof(Export, code) + 3*sizeof(BeamInstr);
Export* ep = (Export *) (((char *)I)-offset);
Uint32 flags;
@@ -4291,26 +4318,25 @@ apply_bif_or_nif_epilogue:
}
E -= 3;
ASSERT(c_p->htop <= E && E <= c_p->hend);
- ASSERT(is_CP((Eterm)(ep->code)));
+ ASSERT(is_CP((BeamInstr)(ep->code)));
ASSERT(is_internal_pid(c_p->tracer_proc) ||
is_internal_port(c_p->tracer_proc));
- E[2] = make_cp(c_p->cp);
+ E[2] = make_cp(c_p->cp); /* XXX:PaN - code in lower range on halfword */
E[1] = am_true; /* Process tracer */
E[0] = make_cp(ep->code);
- c_p->cp = (Eterm*)
- make_cp(flags & MATCH_SET_EXCEPTION_TRACE
- ? beam_exception_trace : beam_return_trace);
+ c_p->cp = (flags & MATCH_SET_EXCEPTION_TRACE)
+ ? beam_exception_trace : beam_return_trace;
erts_smp_proc_lock(c_p, ERTS_PROC_LOCKS_ALL_MINOR);
c_p->trace_flags |= F_EXCEPTION_TRACE;
erts_smp_proc_unlock(c_p, ERTS_PROC_LOCKS_ALL_MINOR);
}
}
- SET_I((Uint *) Arg(0));
+ SET_I((BeamInstr *)Arg(0));
Dispatch();
}
OpCase(return_trace): {
- Uint* code = (Uint *) E[0];
+ BeamInstr* code = (BeamInstr *) (UWord) E[0];
SWAPOUT; /* Needed for shared heap */
ERTS_SMP_UNREQ_PROC_MAIN_LOCK(c_p);
@@ -4318,24 +4344,24 @@ apply_bif_or_nif_epilogue:
ERTS_SMP_REQ_PROC_MAIN_LOCK(c_p);
SWAPIN;
c_p->cp = NULL;
- SET_I((Eterm *) E[2]);
+ SET_I((BeamInstr *) cp_val(E[2]));
E += 3;
Goto(*I);
}
OpCase(i_count_breakpoint): {
- Uint real_I;
+ BeamInstr real_I;
- ErtsCountBreak((Uint *) I, &real_I);
+ ErtsCountBreak((BeamInstr *) I, &real_I);
ASSERT(VALID_INSTR(real_I));
Goto(real_I);
}
OpCase(i_trace_breakpoint):
if (! IS_TRACED_FL(c_p, F_TRACE_CALLS)) {
- Uint real_I;
+ BeamInstr real_I;
- ErtsBreakSkip((Uint *) I, &real_I);
+ ErtsBreakSkip((BeamInstr *) I, &real_I);
Goto(real_I);
}
/* Fall through to next case */
@@ -4349,11 +4375,10 @@ apply_bif_or_nif_epilogue:
SWAPOUT;
reg[0] = r(0);
- if (*cp_val((Eterm)c_p->cp)
- == (Uint) OpCode(return_trace)) {
+ if (*(c_p->cp) == (BeamInstr) OpCode(return_trace)) {
cpp = (Uint*)&E[2];
- } else if (*cp_val((Eterm)c_p->cp)
- == (Uint) OpCode(i_return_to_trace)) {
+ } else if (*(c_p->cp)
+ == (BeamInstr) OpCode(i_return_to_trace)) {
return_to_trace = !0;
cpp = (Uint*)&E[0];
} else {
@@ -4364,19 +4389,19 @@ apply_bif_or_nif_epilogue:
* return_trace and/or i_return_to_trace stackframes
* on the stack, they are not intermixed with y registers
*/
- Eterm *cp_save = c_p->cp;
+ BeamInstr *cp_save = c_p->cp;
for (;;) {
ASSERT(is_CP(*cpp));
- if (*cp_val(*cpp) == (Uint) OpCode(return_trace)) {
+ if (*cp_val(*cpp) == (BeamInstr) OpCode(return_trace)) {
cpp += 3;
- } else if (*cp_val(*cpp) == (Uint) OpCode(i_return_to_trace)) {
+ } else if (*cp_val(*cpp) == (BeamInstr) OpCode(i_return_to_trace)) {
return_to_trace = !0;
cpp += 1;
} else
break;
}
- c_p->cp = (Eterm *) *cpp;
- ASSERT(is_CP((Eterm)c_p->cp));
+ c_p->cp = (BeamInstr *) cp_val(*cpp);
+ ASSERT(is_CP(*cpp));
ERTS_SMP_UNREQ_PROC_MAIN_LOCK(c_p);
real_I = erts_trace_break(c_p, I, reg, &flags, &tracer_pid);
ERTS_SMP_REQ_PROC_MAIN_LOCK(c_p);
@@ -4412,12 +4437,12 @@ apply_bif_or_nif_epilogue:
E -= 1;
ASSERT(c_p->htop <= E && E <= c_p->hend);
E[0] = make_cp(c_p->cp);
- c_p->cp = (Eterm *) make_cp(beam_return_to_trace);
+ c_p->cp = (BeamInstr *) beam_return_to_trace;
}
if (flags & MATCH_SET_RX_TRACE) {
E -= 3;
ASSERT(c_p->htop <= E && E <= c_p->hend);
- ASSERT(is_CP((Eterm) (I - 3)));
+ ASSERT(is_CP((Eterm) (UWord) (I - 3)));
ASSERT(am_true == tracer_pid ||
is_internal_pid(tracer_pid) || is_internal_port(tracer_pid));
E[2] = make_cp(c_p->cp);
@@ -4425,9 +4450,9 @@ apply_bif_or_nif_epilogue:
E[0] = make_cp(I - 3); /* We ARE at the beginning of an
instruction,
the funcinfo is above i. */
- c_p->cp = (Eterm*)
- make_cp(flags & MATCH_SET_EXCEPTION_TRACE
- ? beam_exception_trace : beam_return_trace);
+ c_p->cp =
+ (flags & MATCH_SET_EXCEPTION_TRACE)
+ ? beam_exception_trace : beam_return_trace;
erts_smp_proc_lock(c_p, ERTS_PROC_LOCKS_ALL_MINOR);
c_p->trace_flags |= F_EXCEPTION_TRACE;
erts_smp_proc_unlock(c_p, ERTS_PROC_LOCKS_ALL_MINOR);
@@ -4440,10 +4465,10 @@ apply_bif_or_nif_epilogue:
Uint *cpp = (Uint*) E;
for(;;) {
ASSERT(is_CP(*cpp));
- if (*cp_val(*cpp) == (Uint) OpCode(return_trace)) {
+ if (*cp_val(*cpp) == (BeamInstr) OpCode(return_trace)) {
do ++cpp; while(is_not_CP(*cpp));
cpp += 2;
- } else if (*cp_val(*cpp) == (Uint) OpCode(i_return_to_trace)) {
+ } else if (*cp_val(*cpp) == (BeamInstr) OpCode(i_return_to_trace)) {
do ++cpp; while(is_not_CP(*cpp));
} else break;
}
@@ -4454,7 +4479,7 @@ apply_bif_or_nif_epilogue:
SWAPIN;
}
c_p->cp = NULL;
- SET_I((Eterm *) E[0]);
+ SET_I((BeamInstr *) cp_val(E[0]));
E += 1;
Goto(*I);
}
@@ -4465,7 +4490,7 @@ apply_bif_or_nif_epilogue:
OpCase(i_global_cons):
{
- Eterm *next;
+ BeamInstr *next;
#ifdef HYBRID
Eterm *hp;
@@ -4487,7 +4512,7 @@ apply_bif_or_nif_epilogue:
OpCase(i_global_tuple):
{
- Eterm *next;
+ BeamInstr *next;
int len;
#ifdef HYBRID
Eterm list;
@@ -4522,7 +4547,7 @@ apply_bif_or_nif_epilogue:
OpCase(i_global_copy):
{
- Eterm *next;
+ BeamInstr *next;
PreFetch(0,next);
#ifdef HYBRID
if (!IS_CONST(r(0)))
@@ -4551,7 +4576,7 @@ apply_bif_or_nif_epilogue:
OpCase(fmove_ql): {
Eterm fr = Arg(1);
- Eterm* next;
+ BeamInstr *next;
PreFetch(2, next);
GET_DOUBLE(Arg(0), *(FloatDef*)ADD_BYTE_OFFSET(freg, fr));
@@ -4561,7 +4586,7 @@ apply_bif_or_nif_epilogue:
OpCase(fmove_dl): {
Eterm targ1;
Eterm fr = Arg(1);
- Eterm* next;
+ BeamInstr *next;
PreFetch(2, next);
GetR(0, targ1);
@@ -4582,7 +4607,7 @@ apply_bif_or_nif_epilogue:
OpCase(fconv_dl): {
Eterm targ1;
Eterm fr = Arg(1);
- Eterm* next;
+ BeamInstr *next;
GetR(0, targ1);
PreFetch(2, next);
@@ -4611,7 +4636,7 @@ apply_bif_or_nif_epilogue:
erl_exit(1, "fclearerror/i_fcheckerror without fpe signals (beam_emu)");
#else
OpCase(fclearerror): {
- Eterm* next;
+ BeamInstr *next;
PreFetch(0, next);
ERTS_FP_CHECK_INIT(c_p);
@@ -4619,7 +4644,7 @@ apply_bif_or_nif_epilogue:
}
OpCase(i_fcheckerror): {
- Eterm* next;
+ BeamInstr *next;
PreFetch(0, next);
ERTS_FP_ERROR(c_p, freg[0].fd, goto fbadarith);
@@ -4633,7 +4658,7 @@ apply_bif_or_nif_epilogue:
OpCase(i_fadd_lll): {
- Eterm* next;
+ BeamInstr *next;
PreFetch(3, next);
ERTS_FP_CHECK_INIT(c_p);
@@ -4642,7 +4667,7 @@ apply_bif_or_nif_epilogue:
NextPF(3, next);
}
OpCase(i_fsub_lll): {
- Eterm* next;
+ BeamInstr *next;
PreFetch(3, next);
ERTS_FP_CHECK_INIT(c_p);
@@ -4651,7 +4676,7 @@ apply_bif_or_nif_epilogue:
NextPF(3, next);
}
OpCase(i_fmul_lll): {
- Eterm* next;
+ BeamInstr *next;
PreFetch(3, next);
ERTS_FP_CHECK_INIT(c_p);
@@ -4660,7 +4685,7 @@ apply_bif_or_nif_epilogue:
NextPF(3, next);
}
OpCase(i_fdiv_lll): {
- Eterm* next;
+ BeamInstr *next;
PreFetch(3, next);
ERTS_FP_CHECK_INIT(c_p);
@@ -4669,7 +4694,7 @@ apply_bif_or_nif_epilogue:
NextPF(3, next);
}
OpCase(i_fnegate_ll): {
- Eterm* next;
+ BeamInstr *next;
PreFetch(2, next);
ERTS_FP_CHECK_INIT(c_p);
@@ -4736,7 +4761,7 @@ apply_bif_or_nif_epilogue:
neg_o_reds = -c_p->def_arg_reg[4];
FCALLS = c_p->fcalls;
SWAPIN;
- switch( c_p->def_arg_reg[3] ) {
+ switch( c_p->def_arg_reg[3] ) { /* XXX:PaN - Halfword wont work with hipe yet... */
case HIPE_MODE_SWITCH_RES_RETURN:
ASSERT(is_value(reg[0]));
MoveReturn(reg[0], r(0));
@@ -4748,7 +4773,7 @@ apply_bif_or_nif_epilogue:
/* This can be used to call any function value, but currently it's
only used to call closures referring to unloaded modules. */
{
- Eterm *next;
+ BeamInstr *next;
next = call_fun(c_p, c_p->arity - 1, reg, THE_NON_VALUE);
SWAPIN;
@@ -4881,13 +4906,13 @@ apply_bif_or_nif_epilogue:
em_call_error_handler = OpCode(call_error_handler);
em_call_traced_function = OpCode(call_traced_function);
em_apply_bif = OpCode(apply_bif);
- beam_apply[0] = (Eterm) OpCode(i_apply);
- beam_apply[1] = (Eterm) OpCode(normal_exit);
- beam_exit[0] = (Eterm) OpCode(error_action_code);
- beam_continue_exit[0] = (Eterm) OpCode(continue_exit);
- beam_return_to_trace[0] = (Eterm) OpCode(i_return_to_trace);
- beam_return_trace[0] = (Eterm) OpCode(return_trace);
- beam_exception_trace[0] = (Eterm) OpCode(return_trace); /* UGLY */
+ beam_apply[0] = (BeamInstr) OpCode(i_apply);
+ beam_apply[1] = (BeamInstr) OpCode(normal_exit);
+ beam_exit[0] = (BeamInstr) OpCode(error_action_code);
+ beam_continue_exit[0] = (BeamInstr) OpCode(continue_exit);
+ beam_return_to_trace[0] = (BeamInstr) OpCode(i_return_to_trace);
+ beam_return_trace[0] = (BeamInstr) OpCode(return_trace);
+ beam_exception_trace[0] = (BeamInstr) OpCode(return_trace); /* UGLY */
/*
* Enter all BIFs into the export table.
@@ -4897,8 +4922,8 @@ apply_bif_or_nif_epilogue:
bif_table[i].name,
bif_table[i].arity);
bif_export[i] = ep;
- ep->code[3] = (Eterm) OpCode(apply_bif);
- ep->code[4] = (Eterm) bif_table[i].f;
+ ep->code[3] = (BeamInstr) OpCode(apply_bif);
+ ep->code[4] = (BeamInstr) bif_table[i].f;
}
return;
@@ -5001,8 +5026,8 @@ Eterm error_atom[NUMBER_EXIT_CODES] = {
* at the point of the original exception.
*/
-static Eterm*
-handle_error(Process* c_p, Eterm* pc, Eterm* reg, BifFunction bf)
+static BeamInstr*
+handle_error(Process* c_p, BeamInstr* pc, Eterm* reg, BifFunction bf)
{
Eterm* hp;
Eterm Value = c_p->fvalue;
@@ -5056,7 +5081,7 @@ handle_error(Process* c_p, Eterm* pc, Eterm* reg, BifFunction bf)
/* Find a handler or die */
if ((c_p->catches > 0 || IS_TRACED_FL(c_p, F_EXCEPTION_TRACE))
&& !(c_p->freason & EXF_PANIC)) {
- Eterm *new_pc;
+ BeamInstr *new_pc;
/* The Beam handler code (catch_end or try_end) checks reg[0]
for THE_NON_VALUE to see if the previous code finished
abnormally. If so, reg[1], reg[2] and reg[3] should hold the
@@ -5082,13 +5107,13 @@ handle_error(Process* c_p, Eterm* pc, Eterm* reg, BifFunction bf)
/*
* Find the nearest catch handler
*/
-static Eterm*
+static BeamInstr*
next_catch(Process* c_p, Eterm *reg) {
int active_catches = c_p->catches > 0;
int have_return_to_trace = 0;
Eterm *ptr, *prev, *return_to_trace_ptr = NULL;
- Uint i_return_trace = beam_return_trace[0];
- Uint i_return_to_trace = beam_return_to_trace[0];
+ BeamInstr i_return_trace = beam_return_trace[0];
+ BeamInstr i_return_to_trace = beam_return_to_trace[0];
ptr = prev = c_p->stop;
ASSERT(is_CP(*ptr));
ASSERT(ptr <= STACK_START(c_p));
@@ -5097,9 +5122,9 @@ next_catch(Process* c_p, Eterm *reg) {
*cp_val(*ptr) != i_return_to_trace))
&& c_p->cp) {
/* Can not follow cp here - code may be unloaded */
- Uint *cpp = cp_val((Eterm) c_p->cp);
+ BeamInstr *cpp = c_p->cp;
if (cpp == beam_exception_trace) {
- erts_trace_exception(c_p, (Eterm*) ptr[0],
+ erts_trace_exception(c_p, cp_val(ptr[0]),
reg[1], reg[2], ptr+1);
/* Skip return_trace parameters */
ptr += 2;
@@ -5123,7 +5148,7 @@ next_catch(Process* c_p, Eterm *reg) {
if (is_catch(*ptr) && active_catches) goto found_catch;
}
if (cp_val(*prev) == beam_exception_trace) {
- erts_trace_exception(c_p, (Eterm*) ptr[0],
+ erts_trace_exception(c_p, cp_val(ptr[0]),
reg[1], reg[2], ptr+1);
}
/* Skip return_trace parameters */
@@ -5252,7 +5277,7 @@ expand_error_value(Process* c_p, Uint freason, Eterm Value) {
*/
static void
-save_stacktrace(Process* c_p, Eterm* pc, Eterm* reg, BifFunction bf,
+save_stacktrace(Process* c_p, BeamInstr* pc, Eterm* reg, BifFunction bf,
Eterm args) {
struct StackTrace* s;
int sz;
@@ -5263,7 +5288,7 @@ save_stacktrace(Process* c_p, Eterm* pc, Eterm* reg, BifFunction bf,
}
/* Create a container for the exception data */
- sz = (offsetof(struct StackTrace, trace) + sizeof(Eterm)*depth
+ sz = (offsetof(struct StackTrace, trace) + sizeof(BeamInstr *)*depth
+ sizeof(Eterm) - 1) / sizeof(Eterm);
s = (struct StackTrace *) HAlloc(c_p, 1 + sz);
/* The following fields are inside the bignum */
@@ -5350,9 +5375,10 @@ save_stacktrace(Process* c_p, Eterm* pc, Eterm* reg, BifFunction bf,
/* Save the actual stack trace */
if (depth > 0) {
- Eterm *ptr, *prev = s->depth ? s->trace[s->depth-1] : NULL;
- Uint i_return_trace = beam_return_trace[0];
- Uint i_return_to_trace = beam_return_to_trace[0];
+ Eterm *ptr;
+ BeamInstr *prev = s->depth ? s->trace[s->depth-1] : NULL;
+ BeamInstr i_return_trace = beam_return_trace[0];
+ BeamInstr i_return_to_trace = beam_return_to_trace[0];
/*
* Traverse the stack backwards and add all unique continuation
* pointers to the buffer, up to the maximum stack trace size.
@@ -5365,7 +5391,7 @@ save_stacktrace(Process* c_p, Eterm* pc, Eterm* reg, BifFunction bf,
*cp_val(*ptr) != i_return_to_trace))
&& c_p->cp) {
/* Can not follow cp here - code may be unloaded */
- Uint *cpp = cp_val((Eterm) c_p->cp);
+ BeamInstr *cpp = c_p->cp;
if (cpp == beam_exception_trace || cpp == beam_return_trace) {
/* Skip return_trace parameters */
ptr += 2;
@@ -5385,7 +5411,7 @@ save_stacktrace(Process* c_p, Eterm* pc, Eterm* reg, BifFunction bf,
/* Skip stack frame variables */
do ++ptr; while (is_not_CP(*ptr));
} else {
- Eterm *cp = (Eterm *)(*ptr);
+ BeamInstr *cp = cp_val(*ptr);
if (cp != prev) {
/* Record non-duplicates only */
prev = cp;
@@ -5457,9 +5483,12 @@ build_stacktrace(Process* c_p, Eterm exc) {
struct StackTrace* s;
Eterm args;
int depth;
- Eterm* current;
+ BeamInstr* current;
+#if HALFWORD_HEAP
+ BeamInstr current_buff[3];
+#endif
Eterm Where = NIL;
- Eterm* next_p = &Where;
+ Eterm *next_p = &Where;
if (! (s = get_trace_from_exc(exc))) {
return NIL;
@@ -5487,7 +5516,14 @@ build_stacktrace(Process* c_p, Eterm exc) {
* (e.g. spawn_link(erlang, abs, [1])).
*/
if (current == NULL) {
+#if HALFWORD_HEAP
+ current = current_buff;
+ current[0] = (BeamInstr) c_p->initial[0];
+ current[1] = (BeamInstr) c_p->initial[1];
+ current[2] = (BeamInstr) c_p->initial[2];
+#else
current = c_p->initial;
+#endif
args = am_true; /* Just in case */
} else {
args = get_args_from_exc(exc);
@@ -5523,7 +5559,7 @@ build_stacktrace(Process* c_p, Eterm exc) {
* Finally, we go through the saved continuation pointers.
*/
for (i = 0; i < depth; i++) {
- Eterm *fi = find_function_from_pc((Eterm *) s->trace[i]);
+ BeamInstr *fi = find_function_from_pc((BeamInstr *) s->trace[i]);
if (fi == NULL) continue;
mfa = TUPLE3(hp, fi[0], fi[1], make_small(fi[2]));
hp += 4;
@@ -5540,7 +5576,7 @@ build_stacktrace(Process* c_p, Eterm exc) {
static Eterm
-call_error_handler(Process* p, Eterm* fi, Eterm* reg)
+call_error_handler(Process* p, BeamInstr* fi, Eterm* reg)
{
Eterm* hp;
Export* ep;
@@ -5588,7 +5624,7 @@ call_error_handler(Process* p, Eterm* fi, Eterm* reg)
}
static Eterm
-call_breakpoint_handler(Process* p, Eterm* fi, Eterm* reg)
+call_breakpoint_handler(Process* p, BeamInstr* fi, Eterm* reg)
{
Eterm* hp;
Export* ep;
@@ -5681,7 +5717,7 @@ apply_setup_error_handler(Process* p, Eterm module, Eterm function, Uint arity,
return ep;
}
-static Uint*
+static BeamInstr*
apply(Process* p, Eterm module, Eterm function, Eterm args, Eterm* reg)
{
int arity;
@@ -5763,7 +5799,7 @@ apply(Process* p, Eterm module, Eterm function, Eterm args, Eterm* reg)
return ep->address;
}
-static Uint*
+static BeamInstr*
fixed_apply(Process* p, Eterm* reg, Uint arity)
{
Export* ep;
@@ -5869,7 +5905,7 @@ hibernate(Process* c_p, Eterm module, Eterm function, Eterm args, Eterm* reg)
c_p->stop = STACK_START(c_p);
c_p->catches = 0;
c_p->i = beam_apply;
- c_p->cp = (Eterm *) beam_apply+1;
+ c_p->cp = (BeamInstr *) beam_apply+1;
/*
* If there are no waiting messages, garbage collect and
@@ -5899,7 +5935,7 @@ hibernate(Process* c_p, Eterm module, Eterm function, Eterm args, Eterm* reg)
return 1;
}
-static Uint*
+static BeamInstr*
call_fun(Process* p, /* Current process. */
int arity, /* Number of arguments for Fun. */
Eterm* reg, /* Contents of registers. */
@@ -5919,7 +5955,7 @@ call_fun(Process* p, /* Current process. */
if (is_fun_header(hdr)) {
ErlFunThing* funp = (ErlFunThing *) fun_val(fun);
ErlFunEntry* fe;
- Eterm* code_ptr;
+ BeamInstr* code_ptr;
Eterm* var_ptr;
int actual_arity;
unsigned num_free;
@@ -6014,8 +6050,12 @@ call_fun(Process* p, /* Current process. */
}
}
} else if (is_export_header(hdr)) {
- Export* ep = (Export *) (export_val(fun))[1];
- int actual_arity = (int) ep->code[2];
+ Export *ep;
+ int actual_arity;
+
+ ep = *((Export **) (export_val(fun) + 1));
+ actual_arity = (int) ep->code[2];
+
if (arity == actual_arity) {
return ep->address;
} else {
@@ -6082,7 +6122,7 @@ call_fun(Process* p, /* Current process. */
}
}
-static Eterm*
+static BeamInstr*
apply_fun(Process* p, Eterm fun, Eterm args, Eterm* reg)
{
int arity;
@@ -6176,7 +6216,7 @@ erts_is_builtin(Eterm Mod, Eterm Name, int arity)
if ((ep = export_get(&e)) == NULL) {
return 0;
}
- return ep->address == ep->code+3 && (ep->code[3] == (Uint) em_apply_bif);
+ return ep->address == ep->code+3 && (ep->code[3] == (BeamInstr) em_apply_bif);
}
diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c
index 99fab28dce..bbfeac5397 100644
--- a/erts/emulator/beam/beam_load.c
+++ b/erts/emulator/beam/beam_load.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1996-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1996-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -51,9 +51,9 @@ ErlDrvBinary* erts_gzinflate_buffer(char*, int);
#define EXPORTED 2
#ifdef NO_JUMP_TABLE
-# define BeamOpCode(Op) ((Uint)(Op))
+# define BeamOpCode(Op) ((BeamInstr)(Op))
#else
-# define BeamOpCode(Op) ((Eterm)beam_ops[Op])
+# define BeamOpCode(Op) ((BeamInstr)beam_ops[Op])
#endif
#if defined(WORDS_BIGENDIAN)
@@ -94,7 +94,7 @@ typedef struct {
typedef struct {
unsigned type; /* Type of operand. */
- Uint val; /* Value of operand. */
+ BeamInstr val; /* Value of operand. */
Uint bigarity; /* Arity for bignumbers (only). */
} GenOpArg;
@@ -142,7 +142,7 @@ typedef struct {
typedef struct {
Eterm function; /* Tagged atom for function. */
int arity; /* Arity. */
- Eterm* address; /* Address to function in code. */
+ BeamInstr* address; /* Address to function in code. */
} ExportEntry;
#define MakeIffId(a, b, c, d) \
@@ -274,13 +274,13 @@ typedef struct {
int num_functions; /* Number of functions in module. */
int num_labels; /* Number of labels. */
int code_buffer_size; /* Size of code buffer in words. */
- Eterm* code; /* Loaded code. */
+ BeamInstr* code; /* Loaded code. */
int ci; /* Current index into loaded code. */
Label* labels;
- Uint put_strings; /* Linked list of put_string instructions. */
- Uint new_bs_put_strings; /* Linked list of i_new_bs_put_string instructions. */
+ BeamInstr put_strings; /* Linked list of put_string instructions. */
+ BeamInstr new_bs_put_strings; /* Linked list of i_new_bs_put_string instructions. */
StringPatch* string_patches; /* Linked list of position into string table to patch. */
- Uint catches; /* Linked list of catch_yf instructions. */
+ BeamInstr catches; /* Linked list of catch_yf instructions. */
unsigned loaded_size; /* Final size of code when loaded. */
byte mod_md5[16]; /* MD5 for module code. */
int may_load_nif; /* true if NIFs may later be loaded for this module */
@@ -341,7 +341,7 @@ typedef struct {
#define GetTagAndValue(Stp, Tag, Val) \
do { \
- Uint __w; \
+ BeamInstr __w; \
GetByte(Stp, __w); \
Tag = __w & 0x07; \
if ((__w & 0x08) == 0) { \
@@ -388,7 +388,7 @@ typedef struct {
goto load_error; \
} else { \
int __n = (N); \
- Uint __result = 0; \
+ BeamInstr __result = 0; \
Stp->file_left -= (unsigned) __n; \
while (__n-- > 0) { \
__result = __result << 8 | *Stp->file_p++; \
@@ -465,7 +465,7 @@ static int bin_load(Process *c_p, ErtsProcLocks c_p_locks,
static void init_state(LoaderState* stp);
static int insert_new_code(Process *c_p, ErtsProcLocks c_p_locks,
Eterm group_leader, Eterm module,
- Eterm* code, Uint size, Uint catches);
+ BeamInstr* code, Uint size, BeamInstr catches);
static int scan_iff_file(LoaderState* stp, Uint* chunk_types,
Uint num_types, Uint num_mandatory);
static int load_atom_table(LoaderState* stp);
@@ -499,8 +499,8 @@ static void load_printf(int line, LoaderState* context, char *fmt, ...);
static int transform_engine(LoaderState* st);
static void id_to_string(Uint id, char* s);
static void new_genop(LoaderState* stp);
-static int get_int_val(LoaderState* stp, Uint len_code, Uint* result);
-static int get_erlang_integer(LoaderState* stp, Uint len_code, Uint* result);
+static int get_int_val(LoaderState* stp, Uint len_code, BeamInstr* result);
+static int get_erlang_integer(LoaderState* stp, Uint len_code, BeamInstr* result);
static int new_label(LoaderState* stp);
static void new_literal_patch(LoaderState* stp, int pos);
static void new_string_patch(LoaderState* stp, int pos);
@@ -513,7 +513,7 @@ static Eterm compilation_info_for_module(Process* p, Eterm mod);
static Eterm native_addresses(Process* p, Eterm mod);
int patch_funentries(Eterm Patchlist);
int patch(Eterm Addresses, Uint fe);
-static int safe_mul(Uint a, Uint b, Uint* resp);
+static int safe_mul(UWord a, UWord b, UWord* resp);
static int must_swap_floats;
@@ -591,7 +591,18 @@ erts_load_module(Process *c_p,
}
return result;
}
-
+/* #define LOAD_MEMORY_HARD_DEBUG 1*/
+
+#if defined(LOAD_MEMORY_HARD_DEBUG) && defined(DEBUG)
+/* Requires allocators ERTS_ALLOC_UTIL_HARD_DEBUG also set in erl_alloc_util.h */
+extern void check_allocators(void);
+extern void check_allocated_block(Uint type, void *blk);
+#define CHKALLOC() check_allocators()
+#define CHKBLK(TYPE,BLK) if ((BLK) != NULL) check_allocated_block((TYPE),(BLK))
+#else
+#define CHKALLOC() /* nothing */
+#define CHKBLK(TYPE,BLK) /* nothing */
+#endif
static int
bin_load(Process *c_p, ErtsProcLocks c_p_locks,
@@ -608,6 +619,12 @@ bin_load(Process *c_p, ErtsProcLocks c_p_locks,
* Scan the IFF file.
*/
+#if defined(LOAD_MEMORY_HARD_DEBUG) && defined(DEBUG)
+ erts_fprintf(stderr,"Loading a module\n");
+#endif
+
+ CHKALLOC();
+ CHKBLK(ERTS_ALC_T_CODE,state.code);
state.file_name = "IFF header for Beam file";
state.file_p = bytes;
state.file_left = unloaded_size;
@@ -619,6 +636,7 @@ bin_load(Process *c_p, ErtsProcLocks c_p_locks,
* Read the header for the code chunk.
*/
+ CHKBLK(ERTS_ALC_T_CODE,state.code);
define_file(&state, "code chunk header", CODE_CHUNK);
if (!read_code_header(&state)) {
goto load_error;
@@ -628,6 +646,7 @@ bin_load(Process *c_p, ErtsProcLocks c_p_locks,
* Read the atom table.
*/
+ CHKBLK(ERTS_ALC_T_CODE,state.code);
define_file(&state, "atom table", ATOM_CHUNK);
if (!load_atom_table(&state)) {
goto load_error;
@@ -637,6 +656,7 @@ bin_load(Process *c_p, ErtsProcLocks c_p_locks,
* Read the import table.
*/
+ CHKBLK(ERTS_ALC_T_CODE,state.code);
define_file(&state, "import table", IMP_CHUNK);
if (!load_import_table(&state)) {
goto load_error;
@@ -646,6 +666,7 @@ bin_load(Process *c_p, ErtsProcLocks c_p_locks,
* Read the lambda (fun) table.
*/
+ CHKBLK(ERTS_ALC_T_CODE,state.code);
if (state.chunks[LAMBDA_CHUNK].size > 0) {
define_file(&state, "lambda (fun) table", LAMBDA_CHUNK);
if (!read_lambda_table(&state)) {
@@ -657,6 +678,7 @@ bin_load(Process *c_p, ErtsProcLocks c_p_locks,
* Read the literal table.
*/
+ CHKBLK(ERTS_ALC_T_CODE,state.code);
if (state.chunks[LITERAL_CHUNK].size > 0) {
define_file(&state, "literals table (constant pool)", LITERAL_CHUNK);
if (!read_literal_table(&state)) {
@@ -668,18 +690,25 @@ bin_load(Process *c_p, ErtsProcLocks c_p_locks,
* Load the code chunk.
*/
+ CHKBLK(ERTS_ALC_T_CODE,state.code);
state.file_name = "code chunk";
state.file_p = state.code_start;
state.file_left = state.code_size;
- if (!load_code(&state) || !freeze_code(&state)) {
+ if (!load_code(&state)) {
goto load_error;
}
+ CHKBLK(ERTS_ALC_T_CODE,state.code);
+ if (!freeze_code(&state)) {
+ goto load_error;
+ }
+
/*
* Read and validate the export table. (This must be done after
* loading the code, because it contains labels.)
*/
+ CHKBLK(ERTS_ALC_T_CODE,state.code);
define_file(&state, "export table", EXP_CHUNK);
if (!read_export_table(&state)) {
goto load_error;
@@ -690,16 +719,25 @@ bin_load(Process *c_p, ErtsProcLocks c_p_locks,
* exported and imported functions. This can't fail.
*/
+ CHKBLK(ERTS_ALC_T_CODE,state.code);
rval = insert_new_code(c_p, c_p_locks, state.group_leader, state.module,
state.code, state.loaded_size, state.catches);
if (rval < 0) {
goto load_error;
}
+ CHKBLK(ERTS_ALC_T_CODE,state.code);
final_touch(&state);
/*
* Loading succeded.
*/
+ CHKBLK(ERTS_ALC_T_CODE,state.code);
+#if defined(LOAD_MEMORY_HARD_DEBUG) && defined(DEBUG)
+ erts_fprintf(stderr,"Loaded %T\n",*modp);
+#if 0
+ debug_dump_code(state.code,state.ci);
+#endif
+#endif
rval = 0;
state.code = NULL; /* Prevent code from being freed. */
*modp = state.module;
@@ -791,7 +829,7 @@ init_state(LoaderState* stp)
static int
insert_new_code(Process *c_p, ErtsProcLocks c_p_locks,
- Eterm group_leader, Eterm module, Eterm* code, Uint size, Uint catches)
+ Eterm group_leader, Eterm module, BeamInstr* code, Uint size, BeamInstr catches)
{
Module* modp;
int rval;
@@ -833,7 +871,7 @@ insert_new_code(Process *c_p, ErtsProcLocks c_p_locks,
modules[i] = modules[i-1];
}
modules[i].start = code;
- modules[i].end = (Eterm *) (((byte *)code) + size);
+ modules[i].end = (BeamInstr *) (((byte *)code) + size);
num_loaded_modules++;
mid_module = &modules[num_loaded_modules/2];
return 0;
@@ -1083,7 +1121,7 @@ load_import_table(LoaderState* stp)
* the BIF function.
*/
if ((e = erts_find_export_entry(mod, func, arity)) != NULL) {
- if (e->code[3] == (Uint) em_apply_bif) {
+ if (e->code[3] == (BeamInstr) em_apply_bif) {
stp->import[i].bf = (BifFunction) e->code[4];
if (func == am_load_nif && mod == am_erlang && arity == 2) {
stp->may_load_nif = 1;
@@ -1151,7 +1189,7 @@ read_export_table(LoaderState* stp)
* redefine).
*/
if ((e = erts_find_export_entry(stp->module, func, arity)) != NULL) {
- if (e->code[3] == (Uint) em_apply_bif) {
+ if (e->code[3] == (BeamInstr) em_apply_bif) {
int j;
for (j = 0; j < sizeof(allow_redef)/sizeof(allow_redef[0]); j++) {
@@ -1220,7 +1258,7 @@ static int
read_literal_table(LoaderState* stp)
{
int i;
- Uint uncompressed_sz;
+ BeamInstr uncompressed_sz;
byte* uncompressed = 0;
GetInt(stp, 4, uncompressed_sz);
@@ -1338,8 +1376,8 @@ read_code_header(LoaderState* stp)
* Initialize code area.
*/
stp->code_buffer_size = erts_next_heap_size(2048 + stp->num_functions, 0);
- stp->code = (Eterm*) erts_alloc(ERTS_ALC_T_CODE,
- sizeof(Eterm) * stp->code_buffer_size);
+ stp->code = (BeamInstr *) erts_alloc(ERTS_ALC_T_CODE,
+ sizeof(BeamInstr) * stp->code_buffer_size);
stp->code[MI_NUM_FUNCTIONS] = stp->num_functions;
stp->ci = MI_FUNCTIONS + stp->num_functions + 1;
@@ -1365,16 +1403,18 @@ read_code_header(LoaderState* stp)
LoadError2(Stp, "bad tag %d; expected %d", Actual, Expected); \
} else {}
-#define Need(w) \
- ASSERT(ci <= code_buffer_size); \
- if (code_buffer_size < ci+(w)) { \
- code_buffer_size = erts_next_heap_size(ci+(w), 0); \
- stp->code = code \
- = (Eterm *) erts_realloc(ERTS_ALC_T_CODE, \
- (void *) code, \
- code_buffer_size * sizeof(Eterm)); \
- }
+#define CodeNeed(w) do { \
+ ASSERT(ci <= code_buffer_size); \
+ if (code_buffer_size < ci+(w)) { \
+ code_buffer_size = erts_next_heap_size(ci+(w), 0); \
+ stp->code = code \
+ = (BeamInstr *) erts_realloc(ERTS_ALC_T_CODE, \
+ (void *) code, \
+ code_buffer_size * sizeof(BeamInstr)); \
+ } \
+} while (0)
+#define TermWords(t) (((t) / (sizeof(BeamInstr)/sizeof(Eterm))) + !!((t) % (sizeof(BeamInstr)/sizeof(Eterm))))
static int
@@ -1387,7 +1427,7 @@ load_code(LoaderState* stp)
char* sign;
int arg; /* Number of current argument. */
int num_specific; /* Number of specific ops for current. */
- Eterm* code;
+ BeamInstr* code;
int code_buffer_size;
int specific;
Uint last_label = 0; /* Number of last label. */
@@ -1446,7 +1486,7 @@ load_code(LoaderState* stp)
if (((First) & 0x08) == 0) { \
Val = (First) >> 4; \
} else if (((First) & 0x10) == 0) { \
- Uint __w; \
+ BeamInstr __w; \
GetByte(Stp, __w); \
Val = (((First) >> 5) << 8) | __w; \
} else { \
@@ -1455,7 +1495,7 @@ load_code(LoaderState* stp)
} while (0)
for (arg = 0; arg < arity; arg++) {
- Uint first;
+ BeamInstr first;
GetByte(stp, first);
last_op->a[arg].type = first & 0x07;
@@ -1464,7 +1504,7 @@ load_code(LoaderState* stp)
if ((first & 0x08) == 0) {
last_op->a[arg].val = first >> 4;
} else if ((first & 0x10) == 0) {
- Uint w;
+ BeamInstr w;
GetByte(stp, w);
ASSERT(first < 0x800);
last_op->a[arg].val = ((first >> 5) << 8) | w;
@@ -1523,7 +1563,7 @@ load_code(LoaderState* stp)
break;
case TAG_z:
{
- Uint ext_tag;
+ BeamInstr ext_tag;
unsigned tag;
GetValue(stp, first, ext_tag);
@@ -1531,14 +1571,14 @@ load_code(LoaderState* stp)
case 0: /* Floating point number */
{
Eterm* hp;
-# ifndef ARCH_64
+#if !defined(ARCH_64) || HALFWORD_HEAP /* XXX:PaN - Should use ARCH_64 variant instead */
Uint high, low;
# endif
last_op->a[arg].val = new_literal(stp, &hp,
FLOAT_SIZE_OBJECT);
hp[0] = HEADER_FLONUM;
last_op->a[arg].type = TAG_q;
-# ifdef ARCH_64
+#if defined(ARCH_64) && !HALFWORD_HEAP
GetInt(stp, 8, hp[1]);
# else
GetInt(stp, 4, high);
@@ -1575,10 +1615,10 @@ load_code(LoaderState* stp)
break;
case 3: /* Allocation list. */
{
- Uint n;
- Uint type;
- Uint val;
- Uint words = 0;
+ BeamInstr n;
+ BeamInstr type;
+ BeamInstr val;
+ BeamInstr words = 0;
stp->new_float_instructions = 1;
GetTagAndValue(stp, tag, n);
@@ -1607,7 +1647,7 @@ load_code(LoaderState* stp)
}
case 4: /* Literal. */
{
- Uint val;
+ BeamInstr val;
GetTagAndValue(stp, tag, val);
VerifyTag(stp, tag, TAG_u);
@@ -1734,7 +1774,7 @@ load_code(LoaderState* stp)
}
stp->specific_op = specific;
- Need(opc[stp->specific_op].sz+2); /* Extra margin for packing */
+ CodeNeed(opc[stp->specific_op].sz+2); /* Extra margin for packing */
code[ci++] = BeamOpCode(stp->specific_op);
}
@@ -1772,7 +1812,7 @@ load_code(LoaderState* stp)
case 'c': /* Tagged constant */
switch (tag) {
case TAG_i:
- code[ci++] = make_small(tmp_op->a[arg].val);
+ code[ci++] = (BeamInstr) make_small((Uint) tmp_op->a[arg].val);
break;
case TAG_a:
code[ci++] = tmp_op->a[arg].val;
@@ -1802,7 +1842,7 @@ load_code(LoaderState* stp)
code[ci++] = make_yreg(tmp_op->a[arg].val);
break;
case TAG_i:
- code[ci++] = make_small(tmp_op->a[arg].val);
+ code[ci++] = (BeamInstr) make_small((Uint)tmp_op->a[arg].val);
break;
case TAG_a:
code[ci++] = tmp_op->a[arg].val;
@@ -1896,12 +1936,12 @@ load_code(LoaderState* stp)
if (stp->import[i].bf == NULL) {
LoadError1(stp, "not a BIF: import table index %d", i);
}
- code[ci++] = (Eterm) stp->import[i].bf;
+ code[ci++] = (BeamInstr) stp->import[i].bf;
break;
- case 'P': /* Byte offset into tuple */
+ case 'P': /* Byte offset into tuple */ /* XXX:PaN - * sizeof(Eterm or Eterm *) ? */
VerifyTag(stp, tag, TAG_u);
tmp = tmp_op->a[arg].val;
- code[ci++] = (Eterm) ((tmp_op->a[arg].val+1) * sizeof(Eterm *));
+ code[ci++] = (BeamInstr) ((tmp_op->a[arg].val+1) * sizeof(Eterm));
break;
case 'l': /* Floating point register. */
VerifyTag(stp, tag_to_letter[tag], *sign);
@@ -1925,17 +1965,17 @@ load_code(LoaderState* stp)
for ( ; arg < tmp_op->arity; arg++) {
switch (tmp_op->a[arg].type) {
case TAG_i:
- Need(1);
+ CodeNeed(1);
code[ci++] = make_small(tmp_op->a[arg].val);
break;
case TAG_u:
case TAG_a:
case TAG_v:
- Need(1);
+ CodeNeed(1);
code[ci++] = tmp_op->a[arg].val;
break;
case TAG_f:
- Need(1);
+ CodeNeed(1);
code[ci] = stp->labels[tmp_op->a[arg].val].patches;
stp->labels[tmp_op->a[arg].val].patches = ci;
ci++;
@@ -1947,24 +1987,41 @@ load_code(LoaderState* stp)
lit = stp->literals[tmp_op->a[arg].val].term;
if (is_big(lit)) {
Eterm* bigp;
+ Eterm *tmp;
Uint size;
+ Uint term_size;
bigp = big_val(lit);
- size = bignum_header_arity(*bigp);
- Need(size+1);
- code[ci++] = *bigp++;
- while (size-- > 0) {
- code[ci++] = *bigp++;
+ term_size = bignum_header_arity(*bigp);
+ size = TermWords(term_size + 1);
+ CodeNeed(size);
+ tmp = (Eterm *) (code + ci);
+ *tmp++ = *bigp++;
+ while (term_size-- > 0) {
+ *tmp++ = *bigp++;
}
+ ci +=size;
} else if (is_float(lit)) {
-#ifdef ARCH_64
- Need(1);
+#if defined(ARCH_64) && !HALFWORD_HEAP
+ CodeNeed(1);
code[ci++] = float_val(stp->literals[tmp_op->a[arg].val].term)[1];
+#elif HALFWORD_HEAP
+ Eterm* fptr;
+ Uint size;
+ Eterm *tmp;
+
+ fptr = float_val(stp->literals[tmp_op->a[arg].val].term)+1;
+ size = TermWords(2);
+ CodeNeed(size);
+ tmp = (Eterm *) (code + ci);
+ *tmp++ = *fptr++;
+ *tmp = *fptr;
+ ci += size;
#else
Eterm* fptr;
fptr = float_val(stp->literals[tmp_op->a[arg].val].term)+1;
- Need(2);
+ CodeNeed(2);
code[ci++] = *fptr++;
code[ci++] = *fptr;
#endif
@@ -1984,10 +2041,10 @@ load_code(LoaderState* stp)
*/
if (opc[stp->specific_op].pack[0]) {
char* prog; /* Program for packing engine. */
- Uint stack[8]; /* Stack. */
- Uint* sp = stack; /* Points to next free position. */
- Uint packed = 0; /* Accumulator for packed operations. */
-
+ BeamInstr stack[8]; /* Stack. */
+ BeamInstr* sp = stack; /* Points to next free position. */
+ BeamInstr packed = 0; /* Accumulator for packed operations. */
+
for (prog = opc[stp->specific_op].pack; *prog; prog++) {
switch (*prog) {
case 'g': /* Get instruction; push on stack. */
@@ -2000,7 +2057,7 @@ load_code(LoaderState* stp)
packed = (packed << BEAM_TIGHT_SHIFT) | code[--ci];
break;
case '6': /* Shift 16 steps */
- packed = (packed << 16) | code[--ci];
+ packed = (packed << BEAM_LOOSE_SHIFT) | code[--ci];
break;
case 'p': /* Put instruction (from stack). */
code[ci++] = *--sp;
@@ -2037,9 +2094,9 @@ load_code(LoaderState* stp)
/* Must make room for call_nif op */
int pad = MIN_FUNC_SZ - (finfo_ix - last_func_start);
ASSERT(pad > 0 && pad < MIN_FUNC_SZ);
- Need(pad);
- sys_memmove(&code[finfo_ix+pad], &code[finfo_ix], FINFO_SZ*sizeof(Eterm));
- sys_memset(&code[finfo_ix], 0, pad*sizeof(Eterm));
+ CodeNeed(pad);
+ sys_memmove(&code[finfo_ix+pad], &code[finfo_ix], FINFO_SZ*sizeof(BeamInstr));
+ sys_memset(&code[finfo_ix], 0, pad*sizeof(BeamInstr));
ci += pad;
stp->labels[last_label].value += pad;
}
@@ -2050,6 +2107,7 @@ load_code(LoaderState* stp)
*/
stp->function = code[ci-2];
stp->arity = code[ci-1];
+
ASSERT(stp->labels[last_label].value == ci - FINFO_SZ);
offset = MI_FUNCTIONS + function_number;
code[offset] = stp->labels[last_label].patches;
@@ -2161,7 +2219,6 @@ load_code(LoaderState* stp)
}
}
-#undef Need
load_error:
return 0;
@@ -2373,7 +2430,7 @@ gen_get_integer2(LoaderState* stp, GenOpArg Fail, GenOpArg Ms, GenOpArg Live,
GenOpArg Flags, GenOpArg Dst)
{
GenOp* op;
- Uint bits;
+ UWord bits;
NEW_GENOP(stp, op);
@@ -2838,14 +2895,14 @@ gen_literal_timeout(LoaderState* stp, GenOpArg Fail, GenOpArg Time)
op->a[1].type = TAG_u;
if (Time.type == TAG_i && (timeout = Time.val) >= 0 &&
-#ifdef ARCH_64
+#if defined(ARCH_64) && !HALFWORD_HEAP
(timeout >> 32) == 0
#else
1
#endif
) {
op->a[1].val = timeout;
-#if !defined(ARCH_64)
+#if !defined(ARCH_64) || HALFWORD_HEAP
} else if (Time.type == TAG_q) {
Eterm big;
@@ -2856,11 +2913,13 @@ gen_literal_timeout(LoaderState* stp, GenOpArg Fail, GenOpArg Time)
if (big_arity(big) > 1 || big_sign(big)) {
goto error;
} else {
- (void) term_to_Uint(big, &op->a[1].val);
+ Uint u;
+ (void) term_to_Uint(big, &u);
+ op->a[1].val = (BeamInstr) u;
}
#endif
} else {
-#if !defined(ARCH_64)
+#if !defined(ARCH_64) || HALFWORD_HEAP
error:
#endif
op->op = genop_i_wait_error_0;
@@ -2883,14 +2942,14 @@ gen_literal_timeout_locked(LoaderState* stp, GenOpArg Fail, GenOpArg Time)
op->a[1].type = TAG_u;
if (Time.type == TAG_i && (timeout = Time.val) >= 0 &&
-#ifdef ARCH_64
+#if defined(ARCH_64) && !HALFWORD_HEAP
(timeout >> 32) == 0
#else
1
#endif
) {
op->a[1].val = timeout;
-#ifndef ARCH_64
+#if !defined(ARCH_64) || HALFWORD_HEAP
} else if (Time.type == TAG_q) {
Eterm big;
@@ -2901,11 +2960,13 @@ gen_literal_timeout_locked(LoaderState* stp, GenOpArg Fail, GenOpArg Time)
if (big_arity(big) > 1 || big_sign(big)) {
goto error;
} else {
- (void) term_to_Uint(big, &op->a[1].val);
+ Uint u;
+ (void) term_to_Uint(big, &u);
+ op->a[1].val = (BeamInstr) u;
}
#endif
} else {
-#ifndef ARCH_64
+#if !defined(ARCH_64) || HALFWORD_HEAP
error:
#endif
op->op = genop_i_wait_error_locked_0;
@@ -3321,7 +3382,7 @@ gen_make_fun2(LoaderState* stp, GenOpArg idx)
op->op = genop_i_make_fun_2;
op->arity = 2;
op->a[0].type = TAG_u;
- op->a[0].val = (Uint) fe;
+ op->a[0].val = (BeamInstr) fe;
op->a[1].type = TAG_u;
op->a[1].val = stp->lambdas[idx.val].num_free;
op->next = NULL;
@@ -3342,21 +3403,21 @@ gen_guard_bif(LoaderState* stp, GenOpArg Fail, GenOpArg Live, GenOpArg Bif,
op->a[1].type = TAG_u;
bf = stp->import[Bif.val].bf;
if (bf == length_1) {
- op->a[1].val = (Uint) (void *) erts_gc_length_1;
+ op->a[1].val = (BeamInstr) (void *) erts_gc_length_1;
} else if (bf == size_1) {
- op->a[1].val = (Uint) (void *) erts_gc_size_1;
+ op->a[1].val = (BeamInstr) (void *) erts_gc_size_1;
} else if (bf == bit_size_1) {
- op->a[1].val = (Uint) (void *) erts_gc_bit_size_1;
+ op->a[1].val = (BeamInstr) (void *) erts_gc_bit_size_1;
} else if (bf == byte_size_1) {
- op->a[1].val = (Uint) (void *) erts_gc_byte_size_1;
+ op->a[1].val = (BeamInstr) (void *) erts_gc_byte_size_1;
} else if (bf == abs_1) {
- op->a[1].val = (Uint) (void *) erts_gc_abs_1;
+ op->a[1].val = (BeamInstr) (void *) erts_gc_abs_1;
} else if (bf == float_1) {
- op->a[1].val = (Uint) (void *) erts_gc_float_1;
+ op->a[1].val = (BeamInstr) (void *) erts_gc_float_1;
} else if (bf == round_1) {
- op->a[1].val = (Uint) (void *) erts_gc_round_1;
+ op->a[1].val = (BeamInstr) (void *) erts_gc_round_1;
} else if (bf == trunc_1) {
- op->a[1].val = (Uint) (void *) erts_gc_trunc_1;
+ op->a[1].val = (BeamInstr) (void *) erts_gc_trunc_1;
} else {
abort();
}
@@ -3376,7 +3437,8 @@ gen_guard_bif(LoaderState* stp, GenOpArg Fail, GenOpArg Live, GenOpArg Bif,
static int
freeze_code(LoaderState* stp)
{
- Eterm* code = stp->code;
+ BeamInstr* code = stp->code;
+ Uint *literal_end = NULL;
Uint index;
int i;
byte* str_table;
@@ -3401,46 +3463,49 @@ freeze_code(LoaderState* stp)
* Calculate the final size of the code.
*/
- size = (stp->ci + stp->total_literal_size) * sizeof(Eterm) +
+ size = (stp->ci * sizeof(BeamInstr)) + (stp->total_literal_size * sizeof(Eterm)) +
strtab_size + attr_size + compile_size;
/*
* Move the code to its final location.
*/
- code = (Eterm *) erts_realloc(ERTS_ALC_T_CODE, (void *) code, size);
-
+ code = (BeamInstr *) erts_realloc(ERTS_ALC_T_CODE, (void *) code, size);
+ CHKBLK(ERTS_ALC_T_CODE,code);
/*
* Place a pointer to the op_int_code_end instruction in the
* function table in the beginning of the file.
*/
- code[MI_FUNCTIONS+stp->num_functions] = (Eterm) (code + stp->ci - 1);
+ code[MI_FUNCTIONS+stp->num_functions] = (BeamInstr) (code + stp->ci - 1);
+ CHKBLK(ERTS_ALC_T_CODE,code);
/*
* Store the pointer to the on_load function.
*/
if (stp->on_load) {
- code[MI_ON_LOAD_FUNCTION_PTR] = (Eterm) (code + stp->on_load);
+ code[MI_ON_LOAD_FUNCTION_PTR] = (BeamInstr) (code + stp->on_load);
} else {
code[MI_ON_LOAD_FUNCTION_PTR] = 0;
}
+ CHKBLK(ERTS_ALC_T_CODE,code);
+ literal_end = (Uint *) (code+stp->ci);
/*
* Place the literal heap directly after the code and fix up all
* put_literal instructions that refer to it.
*/
{
- Eterm* ptr;
- Eterm* low;
- Eterm* high;
+ Uint* ptr;
+ Uint* low;
+ Uint* high;
LiteralPatch* lp;
- low = code+stp->ci;
+ low = (Uint *) (code+stp->ci);
high = low + stp->total_literal_size;
- code[MI_LITERALS_START] = (Eterm) low;
- code[MI_LITERALS_END] = (Eterm) high;
+ code[MI_LITERALS_START] = (BeamInstr) low;
+ code[MI_LITERALS_END] = (BeamInstr) high;
ptr = low;
for (i = 0; i < stp->num_literals; i++) {
Uint offset;
@@ -3472,7 +3537,7 @@ freeze_code(LoaderState* stp)
}
lp = stp->literal_patches;
while (lp != 0) {
- Uint* op_ptr;
+ BeamInstr* op_ptr;
Uint literal;
Literal* lit;
@@ -3485,38 +3550,48 @@ freeze_code(LoaderState* stp)
op_ptr[0] = literal;
lp = lp->next;
}
- stp->ci += stp->total_literal_size;
+ literal_end += stp->total_literal_size;
}
/*
* Place the string table and, optionally, attributes, after the literal heap.
*/
+ CHKBLK(ERTS_ALC_T_CODE,code);
- sys_memcpy(code+stp->ci, stp->chunks[STR_CHUNK].start, strtab_size);
- str_table = (byte *) (code+stp->ci);
+ sys_memcpy(literal_end, stp->chunks[STR_CHUNK].start, strtab_size);
+ CHKBLK(ERTS_ALC_T_CODE,code);
+ str_table = (byte *) literal_end;
if (attr_size) {
byte* attr = str_table + strtab_size;
sys_memcpy(attr, stp->chunks[ATTR_CHUNK].start, stp->chunks[ATTR_CHUNK].size);
- code[MI_ATTR_PTR] = (Eterm) attr;
- code[MI_ATTR_SIZE] = (Eterm) stp->chunks[ATTR_CHUNK].size;
+ code[MI_ATTR_PTR] = (BeamInstr) attr;
+ code[MI_ATTR_SIZE] = (BeamInstr) stp->chunks[ATTR_CHUNK].size;
decoded_size = erts_decode_ext_size(attr, attr_size, 0);
if (decoded_size < 0) {
LoadError0(stp, "bad external term representation of module attributes");
}
code[MI_ATTR_SIZE_ON_HEAP] = decoded_size;
}
+ CHKBLK(ERTS_ALC_T_CODE,code);
if (compile_size) {
byte* compile_info = str_table + strtab_size + attr_size;
+ CHKBLK(ERTS_ALC_T_CODE,code);
sys_memcpy(compile_info, stp->chunks[COMPILE_CHUNK].start,
stp->chunks[COMPILE_CHUNK].size);
- code[MI_COMPILE_PTR] = (Eterm) compile_info;
- code[MI_COMPILE_SIZE] = (Eterm) stp->chunks[COMPILE_CHUNK].size;
+ CHKBLK(ERTS_ALC_T_CODE,code);
+ code[MI_COMPILE_PTR] = (BeamInstr) compile_info;
+ CHKBLK(ERTS_ALC_T_CODE,code);
+ code[MI_COMPILE_SIZE] = (BeamInstr) stp->chunks[COMPILE_CHUNK].size;
+ CHKBLK(ERTS_ALC_T_CODE,code);
decoded_size = erts_decode_ext_size(compile_info, compile_size, 0);
+ CHKBLK(ERTS_ALC_T_CODE,code);
if (decoded_size < 0) {
LoadError0(stp, "bad external term representation of compilation information");
}
+ CHKBLK(ERTS_ALC_T_CODE,code);
code[MI_COMPILE_SIZE_ON_HEAP] = decoded_size;
}
+ CHKBLK(ERTS_ALC_T_CODE,code);
/*
@@ -3529,9 +3604,10 @@ freeze_code(LoaderState* stp)
while (index != 0) {
Uint next = code[index];
code[index] = BeamOpCode(op_put_string_IId);
- code[index+2] = (Uint) (str_table + code[index+2] + code[index+1] - 1);
+ code[index+2] = (BeamInstr) (str_table + code[index+2] + code[index+1] - 1);
index = next;
}
+ CHKBLK(ERTS_ALC_T_CODE,code);
/*
* Go through all i_new_bs_put_strings instructions, restore the pointer to
@@ -3543,23 +3619,25 @@ freeze_code(LoaderState* stp)
while (index != 0) {
Uint next = code[index];
code[index] = BeamOpCode(op_bs_put_string_II);
- code[index+2] = (Uint) (str_table + code[index+2]);
+ code[index+2] = (BeamInstr) (str_table + code[index+2]);
index = next;
}
+ CHKBLK(ERTS_ALC_T_CODE,code);
{
StringPatch* sp = stp->string_patches;
while (sp != 0) {
- Uint* op_ptr;
+ BeamInstr* op_ptr;
byte* strp;
op_ptr = code + sp->pos;
strp = str_table + op_ptr[0];
- op_ptr[0] = (Eterm) strp;
+ op_ptr[0] = (BeamInstr) strp;
sp = sp->next;
}
}
+ CHKBLK(ERTS_ALC_T_CODE,code);
/*
* Resolve all labels.
@@ -3579,10 +3657,11 @@ freeze_code(LoaderState* stp)
ASSERT(this_patch < stp->ci);
next_patch = code[this_patch];
ASSERT(next_patch < stp->ci);
- code[this_patch] = (Uint) (code + value);
+ code[this_patch] = (BeamInstr) (code + value);
this_patch = next_patch;
}
}
+ CHKBLK(ERTS_ALC_T_CODE,code);
/*
* Fix all catch_yf instructions.
@@ -3590,13 +3669,14 @@ freeze_code(LoaderState* stp)
index = stp->catches;
catches = BEAM_CATCHES_NIL;
while (index != 0) {
- Uint next = code[index];
+ BeamInstr next = code[index];
code[index] = BeamOpCode(op_catch_yf);
- catches = beam_catches_cons((Uint*)code[index+2], catches);
+ catches = beam_catches_cons((BeamInstr *)code[index+2], catches);
code[index+2] = make_catch(catches);
index = next;
}
stp->catches = catches;
+ CHKBLK(ERTS_ALC_T_CODE,code);
/*
* Save the updated code pointer and code size.
@@ -3605,6 +3685,7 @@ freeze_code(LoaderState* stp)
stp->code = code;
stp->loaded_size = size;
+ CHKBLK(ERTS_ALC_T_CODE,code);
return 1;
load_error:
@@ -3638,7 +3719,7 @@ final_touch(LoaderState* stp)
* callable yet.
*/
ep->address = ep->code+3;
- ep->code[4] = (Eterm) stp->export[i].address;
+ ep->code[4] = (BeamInstr) stp->export[i].address;
}
}
@@ -3650,14 +3731,14 @@ final_touch(LoaderState* stp)
Eterm mod;
Eterm func;
Uint arity;
- Uint import;
+ BeamInstr import;
Uint current;
Uint next;
mod = stp->import[i].module;
func = stp->import[i].function;
arity = stp->import[i].arity;
- import = (Uint) erts_export_put(mod, func, arity);
+ import = (BeamInstr) erts_export_put(mod, func, arity);
current = stp->import[i].patches;
while (current != 0) {
ASSERT(current < stp->ci);
@@ -3675,7 +3756,7 @@ final_touch(LoaderState* stp)
for (i = 0; i < stp->num_lambdas; i++) {
unsigned entry_label = stp->lambdas[i].label;
ErlFunEntry* fe = stp->lambdas[i].fe;
- Eterm* code_ptr = (Eterm *) (stp->code + stp->labels[entry_label].value);
+ BeamInstr* code_ptr = (BeamInstr *) (stp->code + stp->labels[entry_label].value);
if (fe->address[0] != 0) {
/*
@@ -3807,7 +3888,7 @@ transform_engine(LoaderState* st)
if (i >= st->num_imports || st->import[i].bf == NULL)
goto restart;
if (bif_number != -1 &&
- bif_export[bif_number]->code[4] != (Uint) st->import[i].bf) {
+ bif_export[bif_number]->code[4] != (BeamInstr) st->import[i].bf) {
goto restart;
}
}
@@ -4071,7 +4152,7 @@ load_printf(int line, LoaderState* context, char *fmt,...)
static int
-get_int_val(LoaderState* stp, Uint len_code, Uint* result)
+get_int_val(LoaderState* stp, Uint len_code, BeamInstr* result)
{
Uint count;
Uint val;
@@ -4103,7 +4184,7 @@ get_int_val(LoaderState* stp, Uint len_code, Uint* result)
static int
-get_erlang_integer(LoaderState* stp, Uint len_code, Uint* result)
+get_erlang_integer(LoaderState* stp, Uint len_code, BeamInstr* result)
{
Uint count;
Sint val;
@@ -4124,11 +4205,12 @@ get_erlang_integer(LoaderState* stp, Uint len_code, Uint* result)
count = len_code + 2;
} else {
Uint tag;
+ UWord len_word;
ASSERT(len_code == 7);
- GetTagAndValue(stp, tag, len_code);
+ GetTagAndValue(stp, tag, len_word);
VerifyTag(stp, TAG_u, tag);
- count = len_code + 9;
+ count = len_word + 9;
}
/*
@@ -4376,7 +4458,7 @@ functions_in_module(Process* p, /* Process whose heap to use. */
Eterm mod) /* Tagged atom for module. */
{
Module* modp;
- Eterm* code;
+ BeamInstr* code;
int i;
Uint num_functions;
Eterm* hp;
@@ -4394,9 +4476,9 @@ functions_in_module(Process* p, /* Process whose heap to use. */
num_functions = code[MI_NUM_FUNCTIONS];
hp = HAlloc(p, 5*num_functions);
for (i = num_functions-1; i >= 0 ; i--) {
- Eterm* func_info = (Eterm *) code[MI_FUNCTIONS+i];
- Eterm name = func_info[3];
- int arity = func_info[4];
+ BeamInstr* func_info = (BeamInstr *) code[MI_FUNCTIONS+i];
+ Eterm name = (Eterm) func_info[3];
+ int arity = (int) func_info[4];
Eterm tuple;
ASSERT(is_atom(name));
@@ -4419,7 +4501,7 @@ static Eterm
native_addresses(Process* p, Eterm mod)
{
Module* modp;
- Eterm* code;
+ BeamInstr* code;
int i;
Eterm* hp;
Uint num_functions;
@@ -4442,9 +4524,9 @@ native_addresses(Process* p, Eterm mod)
hp = HAlloc(p, need);
hp_end = hp + need;
for (i = num_functions-1; i >= 0 ; i--) {
- Eterm* func_info = (Eterm *) code[MI_FUNCTIONS+i];
- Eterm name = func_info[3];
- int arity = func_info[4];
+ BeamInstr* func_info = (BeamInstr *) code[MI_FUNCTIONS+i];
+ Eterm name = (Eterm) func_info[3];
+ int arity = (int) func_info[4];
Eterm tuple;
ASSERT(is_atom(name));
@@ -4486,7 +4568,7 @@ exported_from_module(Process* p, /* Process whose heap to use. */
Eterm tuple;
if (ep->address == ep->code+3 &&
- ep->code[3] == (Eterm) em_call_error_handler) {
+ ep->code[3] == (BeamInstr) em_call_error_handler) {
/* There is a call to the function, but it does not exist. */
continue;
}
@@ -4519,7 +4601,7 @@ attributes_for_module(Process* p, /* Process whose heap to use. */
{
Module* modp;
- Eterm* code;
+ BeamInstr* code;
Eterm* hp;
byte* ext;
Eterm result = NIL;
@@ -4559,7 +4641,7 @@ compilation_info_for_module(Process* p, /* Process whose heap to use. */
Eterm mod) /* Tagged atom for module. */
{
Module* modp;
- Eterm* code;
+ BeamInstr* code;
Eterm* hp;
byte* ext;
Eterm result = NIL;
@@ -4591,8 +4673,8 @@ compilation_info_for_module(Process* p, /* Process whose heap to use. */
/*
* Returns a pointer to {module, function, arity}, or NULL if not found.
*/
-Eterm*
-find_function_from_pc(Eterm* pc)
+BeamInstr *
+find_function_from_pc(BeamInstr* pc)
{
Range* low = modules;
Range* high = low + num_loaded_modules;
@@ -4604,9 +4686,9 @@ find_function_from_pc(Eterm* pc)
} else if (pc > mid->end) {
low = mid + 1;
} else {
- Eterm** low1 = (Eterm **) (mid->start + MI_FUNCTIONS);
- Eterm** high1 = low1 + mid->start[MI_NUM_FUNCTIONS];
- Eterm** mid1;
+ BeamInstr** low1 = (BeamInstr **) (mid->start + MI_FUNCTIONS);
+ BeamInstr** high1 = low1 + mid->start[MI_NUM_FUNCTIONS];
+ BeamInstr** mid1;
while (low1 < high1) {
mid1 = low1 + (high1-low1) / 2;
@@ -4719,10 +4801,10 @@ code_module_md5_1(Process* p, Eterm Bin)
#define WORDS_PER_FUNCTION 6
-static Eterm*
-make_stub(Eterm* fp, Eterm mod, Eterm func, Uint arity, Uint native, Eterm OpCode)
+static BeamInstr*
+make_stub(BeamInstr* fp, Eterm mod, Eterm func, Uint arity, Uint native, BeamInstr OpCode)
{
- fp[0] = (Eterm) BeamOp(op_i_func_info_IaaI);
+ fp[0] = (BeamInstr) BeamOp(op_i_func_info_IaaI);
fp[1] = native;
fp[2] = mod;
fp[3] = func;
@@ -4741,14 +4823,14 @@ static byte*
stub_copy_info(LoaderState* stp,
int chunk, /* Chunk: ATTR_CHUNK or COMPILE_CHUNK */
byte* info, /* Where to store info. */
- Eterm* ptr_word, /* Where to store pointer into info. */
- Eterm* size_word) /* Where to store size of info. */
+ BeamInstr* ptr_word, /* Where to store pointer into info. */
+ BeamInstr* size_word) /* Where to store size of info. */
{
Sint decoded_size;
Uint size = stp->chunks[chunk].size;
if (size != 0) {
memcpy(info, stp->chunks[chunk].start, size);
- *ptr_word = (Eterm) info;
+ *ptr_word = (BeamInstr) info;
decoded_size = erts_decode_ext_size(info, size, 0);
if (decoded_size < 0) {
return 0;
@@ -4791,7 +4873,7 @@ stub_read_export_table(LoaderState* stp)
}
static void
-stub_final_touch(LoaderState* stp, Eterm* fp)
+stub_final_touch(LoaderState* stp, BeamInstr* fp)
{
int i;
int n = stp->num_exps;
@@ -4978,12 +5060,12 @@ Eterm
erts_make_stub_module(Process* p, Eterm Mod, Eterm Beam, Eterm Info)
{
LoaderState state;
- Eterm Funcs;
- Eterm Patchlist;
+ BeamInstr Funcs;
+ BeamInstr Patchlist;
Eterm* tp;
- Eterm* code = NULL;
- Eterm* ptrs;
- Eterm* fp;
+ BeamInstr* code = NULL;
+ BeamInstr* ptrs;
+ BeamInstr* fp;
byte* info;
Uint ci;
int n;
@@ -5072,7 +5154,7 @@ erts_make_stub_module(Process* p, Eterm Mod, Eterm Beam, Eterm Info)
* Allocate memory for the stub module.
*/
- code_size = ((WORDS_PER_FUNCTION+1)*n + MI_FUNCTIONS + 2) * sizeof(Eterm);
+ code_size = ((WORDS_PER_FUNCTION+1)*n + MI_FUNCTIONS + 2) * sizeof(BeamInstr);
code_size += state.chunks[ATTR_CHUNK].size;
code_size += state.chunks[COMPILE_CHUNK].size;
code = erts_alloc_fnf(ERTS_ALC_T_CODE, code_size);
@@ -5141,7 +5223,7 @@ erts_make_stub_module(Process* p, Eterm Mod, Eterm Beam, Eterm Info)
* Set the pointer and make the stub. Put a return instruction
* as the body until we know what kind of trap we should put there.
*/
- ptrs[i] = (Eterm) fp;
+ ptrs[i] = (BeamInstr) fp;
#ifdef HIPE
op = (Eterm) BeamOpCode(op_hipe_trap_call); /* Might be changed later. */
#else
@@ -5154,8 +5236,8 @@ erts_make_stub_module(Process* p, Eterm Mod, Eterm Beam, Eterm Info)
* Insert the last pointer and the int_code_end instruction.
*/
- ptrs[i] = (Eterm) fp;
- *fp++ = (Eterm) BeamOp(op_int_code_end);
+ ptrs[i] = (BeamInstr) fp;
+ *fp++ = (BeamInstr) BeamOp(op_int_code_end);
/*
* Copy attributes and compilation information.
@@ -5222,9 +5304,9 @@ erts_make_stub_module(Process* p, Eterm Mod, Eterm Beam, Eterm Info)
#undef WORDS_PER_FUNCTION
-static int safe_mul(Uint a, Uint b, Uint* resp)
+static int safe_mul(UWord a, UWord b, UWord* resp)
{
- Uint res = a * b;
+ Uint res = a * b; /* XXX:Pan - used in bit syntax, the multiplication has to be stored in Uint */
*resp = res;
if (b == 0) {
diff --git a/erts/emulator/beam/beam_load.h b/erts/emulator/beam/beam_load.h
index c17844a553..26e3054c4b 100644
--- a/erts/emulator/beam/beam_load.h
+++ b/erts/emulator/beam/beam_load.h
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1999-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1999-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -44,13 +44,13 @@ extern void** beam_ops;
#endif
-extern Eterm beam_debug_apply[];
-extern Eterm* em_call_error_handler;
-extern Eterm* em_apply_bif;
-extern Eterm* em_call_traced_function;
+extern BeamInstr beam_debug_apply[];
+extern BeamInstr* em_call_error_handler;
+extern BeamInstr* em_apply_bif;
+extern BeamInstr* em_call_traced_function;
typedef struct {
- Eterm* start; /* Pointer to start of module. */
- Eterm* end; /* Points one word beyond last function in module. */
+ BeamInstr* start; /* Pointer to start of module. */
+ BeamInstr* end; /* Points one word beyond last function in module. */
} Range;
/*
diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c
index 1b670585a7..85bf584337 100644
--- a/erts/emulator/beam/bif.c
+++ b/erts/emulator/beam/bif.c
@@ -616,13 +616,15 @@ local_name_monitor(Process *p, Eterm target_name)
rp = erts_whereis_process(p, p_locks, target_name, ERTS_PROC_LOCK_LINK,
ERTS_P2P_FLG_ALLOW_OTHER_X);
if (!rp) {
- Eterm lhp[3];
+ DeclareTmpHeap(lhp,3,p);
Eterm item;
+ UseTmpHeap(3,p);
erts_smp_proc_unlock(p, ERTS_PROC_LOCK_LINK);
p_locks &= ~ERTS_PROC_LOCK_LINK;
item = TUPLE2(lhp, target_name, erts_this_dist_entry->sysname);
erts_queue_monitor_message(p, &p_locks,
mon_ref, am_process, item, am_noproc);
+ UnUseTmpHeap(3,p);
}
else if (rp != p) {
erts_add_monitor(&(p->monitors), MON_ORIGIN, mon_ref, rp->id,
@@ -3466,9 +3468,16 @@ BIF_RETTYPE make_fun_3(BIF_ALIST_3)
if (arity < 0) {
goto error;
}
+#if HALFWORD_HEAP
+ hp = HAlloc(BIF_P, 3);
+ hp[0] = HEADER_EXPORT;
+ /* Yes, May be misaligned, but X86_64 will fix it... */
+ *((Export **) (hp+1)) = erts_export_get_or_make_stub(BIF_ARG_1, BIF_ARG_2, (Uint) arity);
+#else
hp = HAlloc(BIF_P, 2);
hp[0] = HEADER_EXPORT;
hp[1] = (Eterm) erts_export_get_or_make_stub(BIF_ARG_1, BIF_ARG_2, (Uint) arity);
+#endif
BIF_RET(make_export(hp));
}
@@ -3884,7 +3893,7 @@ BIF_RETTYPE hash_2(BIF_ALIST_2)
if ((range = signed_val(BIF_ARG_2)) <= 0) { /* [1..MAX_SMALL] */
BIF_ERROR(BIF_P, BADARG);
}
-#ifdef ARCH_64
+#if defined(ARCH_64) && !HALFWORD_HEAP
if (range > ((1L << 27) - 1))
BIF_ERROR(BIF_P, BADARG);
#endif
@@ -3956,7 +3965,7 @@ BIF_RETTYPE phash2_2(BIF_ALIST_2)
/*
* Return either a small or a big. Use the heap for bigs if there is room.
*/
-#ifdef ARCH_64
+#if defined(ARCH_64) && !HALFWORD_HEAP
BIF_RET(make_small(final_hash));
#else
if (IS_USMALL(0, final_hash)) {
@@ -4118,8 +4127,8 @@ void erts_init_bif(void)
#else
bif_return_trap_export.code[2] = 1;
#endif
- bif_return_trap_export.code[3] = (Eterm) em_apply_bif;
- bif_return_trap_export.code[4] = (Eterm) &bif_return_trap;
+ bif_return_trap_export.code[3] = (BeamInstr) em_apply_bif;
+ bif_return_trap_export.code[4] = (BeamInstr) &bif_return_trap;
flush_monitor_message_trap = erts_export_put(am_erlang,
am_flush_monitor_message,
diff --git a/erts/emulator/beam/bif.h b/erts/emulator/beam/bif.h
index 05e9b78c28..50f5f4fbd6 100644
--- a/erts/emulator/beam/bif.h
+++ b/erts/emulator/beam/bif.h
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1996-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1996-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -125,7 +125,7 @@ do { \
#define ERTS_BIF_PREP_TRAP0(Ret, Trap, Proc) \
do { \
(Proc)->arity = 0; \
- (Proc)->def_arg_reg[3] = (Eterm) (Trap->address); \
+ *((UWord *) (UWord) ((Proc)->def_arg_reg + 3)) = (UWord) ((Trap)->address); \
(Proc)->freason = TRAP; \
(Ret) = THE_NON_VALUE; \
} while (0)
@@ -134,7 +134,8 @@ do { \
do { \
(Proc)->arity = 1; \
(Proc)->def_arg_reg[0] = (Eterm) (A0); \
- (Proc)->def_arg_reg[3] = (Eterm) ((Trap)->address); \
+ *((UWord *) (UWord) ((Proc)->def_arg_reg + 3)) = (UWord) ((Trap)->address); \
+ (Proc)->def_arg_reg[3] = (UWord) ((Trap)->address); \
(Proc)->freason = TRAP; \
(Ret) = THE_NON_VALUE; \
} while (0)
@@ -144,7 +145,8 @@ do { \
(Proc)->arity = 2; \
(Proc)->def_arg_reg[0] = (Eterm) (A0); \
(Proc)->def_arg_reg[1] = (Eterm) (A1); \
- (Proc)->def_arg_reg[3] = (Eterm) ((Trap)->address); \
+ *((UWord *) (UWord) ((Proc)->def_arg_reg + 3)) = (UWord) ((Trap)->address); \
+ (Proc)->def_arg_reg[3] = (UWord) ((Trap)->address); \
(Proc)->freason = TRAP; \
(Ret) = THE_NON_VALUE; \
} while (0)
@@ -155,14 +157,15 @@ do { \
(Proc)->def_arg_reg[0] = (Eterm) (A0); \
(Proc)->def_arg_reg[1] = (Eterm) (A1); \
(Proc)->def_arg_reg[2] = (Eterm) (A2); \
- (Proc)->def_arg_reg[3] = (Eterm) ((Trap)->address); \
+ *((UWord *) (UWord) ((Proc)->def_arg_reg + 3)) = (UWord) ((Trap)->address); \
+ (Proc)->def_arg_reg[3] = (UWord) ((Trap)->address); \
(Proc)->freason = TRAP; \
(Ret) = THE_NON_VALUE; \
} while (0)
#define BIF_TRAP0(p, Trap_) do { \
(p)->arity = 0; \
- (p)->def_arg_reg[3] = (Eterm) ((Trap_)->address); \
+ *((UWord *) (UWord) ((p)->def_arg_reg + 3)) = (UWord) ((Trap_)->address); \
(p)->freason = TRAP; \
return THE_NON_VALUE; \
} while(0)
@@ -170,7 +173,7 @@ do { \
#define BIF_TRAP1(Trap_, p, A0) do { \
(p)->arity = 1; \
(p)->def_arg_reg[0] = (A0); \
- (p)->def_arg_reg[3] = (Eterm) ((Trap_)->address); \
+ *((UWord *) (UWord) ((p)->def_arg_reg + 3)) = (UWord) ((Trap_)->address); \
(p)->freason = TRAP; \
return THE_NON_VALUE; \
} while(0)
@@ -179,7 +182,7 @@ do { \
(p)->arity = 2; \
(p)->def_arg_reg[0] = (A0); \
(p)->def_arg_reg[1] = (A1); \
- (p)->def_arg_reg[3] = (Eterm) ((Trap_)->address); \
+ *((UWord *) (UWord) ((p)->def_arg_reg + 3)) = (UWord) ((Trap_)->address); \
(p)->freason = TRAP; \
return THE_NON_VALUE; \
} while(0)
@@ -189,14 +192,14 @@ do { \
(p)->def_arg_reg[0] = (A0); \
(p)->def_arg_reg[1] = (A1); \
(p)->def_arg_reg[2] = (A2); \
- (p)->def_arg_reg[3] = (Eterm) ((Trap_)->address); \
+ *((UWord *) (UWord) ((p)->def_arg_reg + 3)) = (UWord) ((Trap_)->address); \
(p)->freason = TRAP; \
return THE_NON_VALUE; \
} while(0)
#define BIF_TRAP_CODE_PTR_0(p, Code_) do { \
(p)->arity = 0; \
- (p)->def_arg_reg[3] = (Eterm) (Code_); \
+ *((UWord *) (UWord) ((p)->def_arg_reg + 3)) = (UWord) (Code_); \
(p)->freason = TRAP; \
return THE_NON_VALUE; \
} while(0)
diff --git a/erts/emulator/beam/big.c b/erts/emulator/beam/big.c
index 03c88da8c6..90d3a0304a 100644
--- a/erts/emulator/beam/big.c
+++ b/erts/emulator/beam/big.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1996-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1996-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -1459,7 +1459,31 @@ Eterm uint_to_big(Uint x, Eterm *y)
BIG_DIGIT(y, 0) = x;
return make_big(y);
}
+/*
+** convert UWord to bigint
+** (must only be used if x is to big to be stored as a small)
+** Allocation is tricky, the heap need has to be calculated
+** with the macro BIG_UWORD_HEAP_SIZE(x)
+*/
+Eterm uword_to_big(UWord x, Eterm *y)
+{
+#if HALFWORD_HEAP
+ Uint upper = x >> 32;
+ Uint lower = x & 0xFFFFFFFFUL;
+ if (upper == 0) {
+ *y = make_pos_bignum_header(1);
+ } else {
+ *y = make_pos_bignum_header(2);
+ BIG_DIGIT(y, 1) = upper;
+ }
+ BIG_DIGIT(y, 0) = lower;
+#else
+ *y = make_pos_bignum_header(1);
+ BIG_DIGIT(y, 0) = x;
+#endif
+ return make_big(y);
+}
/*
** convert signed int to bigint
@@ -1480,7 +1504,7 @@ Eterm small_to_big(Sint x, Eterm *y)
Eterm erts_uint64_to_big(Uint64 x, Eterm **hpp)
{
Eterm *hp = *hpp;
-#ifdef ARCH_32
+#if defined(ARCH_32) || HALFWORD_HEAP
if (x >= (((Uint64) 1) << 32)) {
*hp = make_pos_bignum_header(2);
BIG_DIGIT(hp, 0) = (Uint) (x & ((Uint) 0xffffffff));
@@ -1507,7 +1531,7 @@ Eterm erts_sint64_to_big(Sint64 x, Eterm **hpp)
neg = 1;
x = -x;
}
-#ifdef ARCH_32
+#if defined(ARCH_32) || HALFWORD_HEAP
if (x >= (((Uint64) 1) << 32)) {
if (neg)
*hp = make_neg_bignum_header(2);
@@ -1854,6 +1878,42 @@ term_to_Uint(Eterm term, Uint *up)
}
}
+int
+term_to_UWord(Eterm term, UWord *up)
+{
+ if (is_small(term)) {
+ Sint i = signed_val(term);
+ if (i < 0) {
+ *up = BADARG;
+ return 0;
+ }
+ *up = (UWord) i;
+ return 1;
+ } else if (is_big(term)) {
+ ErtsDigit* xr = big_v(term);
+ dsize_t xl = big_size(term);
+ UWord uval = 0;
+ int n = 0;
+
+ if (big_sign(term)) {
+ *up = BADARG;
+ return 0;
+ } else if (xl*D_EXP > sizeof(UWord)*8) {
+ *up = SYSTEM_LIMIT;
+ return 0;
+ }
+ while (xl-- > 0) {
+ uval |= ((Uint)(*xr++)) << n;
+ n += D_EXP;
+ }
+ *up = uval;
+ return 1;
+ } else {
+ *up = BADARG;
+ return 0;
+ }
+}
+
int term_to_Sint(Eterm term, Sint *sp)
{
if (is_small(term)) {
diff --git a/erts/emulator/beam/big.h b/erts/emulator/beam/big.h
index b8e38d482c..56f3be372a 100644
--- a/erts/emulator/beam/big.h
+++ b/erts/emulator/beam/big.h
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1996-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1996-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -34,7 +34,7 @@
typedef Uint ErtsDigit;
-#if (SIZEOF_VOID_P == 4) && defined(SIZEOF_LONG_LONG) && (SIZEOF_LONG_LONG == 8)
+#if ((SIZEOF_VOID_P == 4) || HALFWORD_HEAP) && defined(SIZEOF_LONG_LONG) && (SIZEOF_LONG_LONG == 8)
/* Assume 32-bit machine with long long support */
typedef Uint64 ErtsDoubleDigit;
typedef Uint16 ErtsHalfDigit;
@@ -58,7 +58,7 @@ typedef Uint32 ErtsHalfDigit;
typedef Uint dsize_t; /* Vector size type */
-#define D_EXP (SIZEOF_VOID_P*8)
+#define D_EXP (ERTS_SIZEOF_ETERM*8)
#define D_MASK ((ErtsDigit)(-1)) /* D_BASE-1 */
/* macros for bignum objects */
@@ -88,7 +88,13 @@ typedef Uint dsize_t; /* Vector size type */
#define BIG_UINT_HEAP_SIZE (1 + 1) /* always, since sizeof(Uint) <= sizeof(Eterm) */
-#ifdef ARCH_32
+#if HALFWORD_HEAP
+#define BIG_UWORD_HEAP_SIZE(UW) (((UW) >> (sizeof(Uint) * 8)) ? 3 : 2)
+#else
+#define BIG_UWORD_HEAP_SIZE(UW) BIG_UINT_HEAP_SIZE
+#endif
+
+#if defined(ARCH_32) || HALFWORD_HEAP
#define ERTS_UINT64_BIG_HEAP_SIZE__(X) \
((X) >= (((Uint64) 1) << 32) ? (1 + 2) : (1 + 1))
@@ -136,6 +142,7 @@ int big_ucomp (Eterm, Eterm);
int big_to_double(Eterm x, double* resp);
Eterm small_to_big(Sint, Eterm*);
Eterm uint_to_big(Uint, Eterm*);
+Eterm uword_to_big(UWord, Eterm*);
Eterm erts_make_integer(Uint, Process *);
dsize_t big_bytes(Eterm);
@@ -143,6 +150,7 @@ Eterm bytes_to_big(byte*, dsize_t, int, Eterm*);
byte* big_to_bytes(Eterm, byte*);
int term_to_Uint(Eterm, Uint*);
+int term_to_UWord(Eterm, UWord*);
int term_to_Sint(Eterm, Sint*);
Uint32 big_to_uint32(Eterm b);
diff --git a/erts/emulator/beam/binary.c b/erts/emulator/beam/binary.c
index 08c64610a2..59c20398d5 100644
--- a/erts/emulator/beam/binary.c
+++ b/erts/emulator/beam/binary.c
@@ -42,7 +42,7 @@ void
erts_init_binary(void)
{
/* Verify Binary alignment... */
- if ((((Uint) &((Binary *) 0)->orig_bytes[0]) % ((Uint) 8)) != 0) {
+ if ((((UWord) &((Binary *) 0)->orig_bytes[0]) % ((UWord) 8)) != 0) {
/* I assume that any compiler should be able to optimize this
away. If not, this test is not very expensive... */
erl_exit(ERTS_ABORT_EXIT,
diff --git a/erts/emulator/beam/break.c b/erts/emulator/beam/break.c
index cc69977b79..d93c031db2 100644
--- a/erts/emulator/beam/break.c
+++ b/erts/emulator/beam/break.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1996-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1996-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
/* This File contains functions which are called if a user hits ^C */
@@ -381,7 +381,7 @@ loaded(int to, void *to_arg)
int i;
int old = 0;
int cur = 0;
- Eterm* code;
+ BeamInstr* code;
/*
* Calculate and print totals.
diff --git a/erts/emulator/beam/dist.c b/erts/emulator/beam/dist.c
index e3094404e2..d465017949 100644
--- a/erts/emulator/beam/dist.c
+++ b/erts/emulator/beam/dist.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1996-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1996-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -228,6 +228,7 @@ int is_node_name_atom(Eterm a)
typedef struct {
DistEntry *dep;
+ Eterm *lhp;
} NetExitsContext;
/*
@@ -253,8 +254,9 @@ static void doit_monitor_net_exits(ErtsMonitor *mon, void *vnecp)
erts_destroy_monitor(rmon);
}
} else {
- Eterm lhp[3];
+ DeclareTmpHeapNoproc(lhp,3);
Eterm watched;
+ UseTmpHeapNoproc(3);
ASSERT(mon->type == MON_TARGET);
rmon = erts_remove_monitor(&(rp->monitors),mon->ref);
/* ASSERT(rmon != NULL); can happen during process exit */
@@ -271,6 +273,7 @@ static void doit_monitor_net_exits(ErtsMonitor *mon, void *vnecp)
watched, am_noconnection);
erts_destroy_monitor(rmon);
}
+ UnUseTmpHeapNoproc(3);
}
erts_smp_proc_unlock(rp, rp_locks);
done:
@@ -632,19 +635,27 @@ static void clear_dist_entry(DistEntry *dep)
int
erts_dsig_send_link(ErtsDSigData *dsdp, Eterm local, Eterm remote)
{
- Eterm ctl_heap[4];
+ DeclareTmpHeapNoproc(ctl_heap,4);
Eterm ctl = TUPLE3(&ctl_heap[0], make_small(DOP_LINK), local, remote);
+ int res;
+ UseTmpHeapNoproc(4);
- return dsig_send(dsdp, ctl, THE_NON_VALUE, 0);
+ res = dsig_send(dsdp, ctl, THE_NON_VALUE, 0);
+ UnUseTmpHeapNoproc(4);
+ return res;
}
int
erts_dsig_send_unlink(ErtsDSigData *dsdp, Eterm local, Eterm remote)
{
- Eterm ctl_heap[4];
+ DeclareTmpHeapNoproc(ctl_heap,4);
Eterm ctl = TUPLE3(&ctl_heap[0], make_small(DOP_UNLINK), local, remote);
+ int res;
- return dsig_send(dsdp, ctl, THE_NON_VALUE, 0);
+ UseTmpHeapNoproc(4);
+ res = dsig_send(dsdp, ctl, THE_NON_VALUE, 0);
+ UnUseTmpHeapNoproc(4);
+ return res;
}
@@ -656,7 +667,10 @@ erts_dsig_send_m_exit(ErtsDSigData *dsdp, Eterm watcher, Eterm watched,
Eterm ref, Eterm reason)
{
Eterm ctl;
- Eterm ctl_heap[6];
+ DeclareTmpHeapNoproc(ctl_heap,6);
+ int res;
+
+ UseTmpHeapNoproc(6);
ctl = TUPLE5(&ctl_heap[0], make_small(DOP_MONITOR_P_EXIT),
watched, watcher, ref, reason);
@@ -667,7 +681,9 @@ erts_dsig_send_m_exit(ErtsDSigData *dsdp, Eterm watcher, Eterm watched,
erts_smp_de_links_unlock(dsdp->dep);
#endif
- return dsig_send(dsdp, ctl, THE_NON_VALUE, 1);
+ res = dsig_send(dsdp, ctl, THE_NON_VALUE, 1);
+ UnUseTmpHeapNoproc(6);
+ return res;
}
/* We want to monitor a process (named or unnamed) on another node, we send:
@@ -678,13 +694,17 @@ erts_dsig_send_monitor(ErtsDSigData *dsdp, Eterm watcher, Eterm watched,
Eterm ref)
{
Eterm ctl;
- Eterm ctl_heap[5];
+ DeclareTmpHeapNoproc(ctl_heap,5);
+ int res;
+ UseTmpHeapNoproc(5);
ctl = TUPLE4(&ctl_heap[0],
make_small(DOP_MONITOR_P),
watcher, watched, ref);
- return dsig_send(dsdp, ctl, THE_NON_VALUE, 0);
+ res = dsig_send(dsdp, ctl, THE_NON_VALUE, 0);
+ UnUseTmpHeapNoproc(5);
+ return res;
}
/* A local process monitoring a remote one wants to stop monitoring, either
@@ -696,23 +716,29 @@ erts_dsig_send_demonitor(ErtsDSigData *dsdp, Eterm watcher,
Eterm watched, Eterm ref, int force)
{
Eterm ctl;
- Eterm ctl_heap[5];
+ DeclareTmpHeapNoproc(ctl_heap,5);
+ int res;
+ UseTmpHeapNoproc(5);
ctl = TUPLE4(&ctl_heap[0],
make_small(DOP_DEMONITOR_P),
watcher, watched, ref);
- return dsig_send(dsdp, ctl, THE_NON_VALUE, force);
+ res = dsig_send(dsdp, ctl, THE_NON_VALUE, force);
+ UnUseTmpHeapNoproc(5);
+ return res;
}
int
erts_dsig_send_msg(ErtsDSigData *dsdp, Eterm remote, Eterm message)
{
Eterm ctl;
- Eterm ctl_heap[5];
+ DeclareTmpHeapNoproc(ctl_heap,5);
Eterm token = NIL;
Process *sender = dsdp->proc;
+ int res;
+ UseTmpHeapNoproc(5);
if (SEQ_TRACE_TOKEN(sender) != NIL) {
seq_trace_update_send(sender);
token = SEQ_TRACE_TOKEN(sender);
@@ -724,17 +750,21 @@ erts_dsig_send_msg(ErtsDSigData *dsdp, Eterm remote, Eterm message)
make_small(DOP_SEND_TT), am_Cookie, remote, token);
else
ctl = TUPLE3(&ctl_heap[0], make_small(DOP_SEND), am_Cookie, remote);
- return dsig_send(dsdp, ctl, message, 0);
+ res = dsig_send(dsdp, ctl, message, 0);
+ UnUseTmpHeapNoproc(5);
+ return res;
}
int
erts_dsig_send_reg_msg(ErtsDSigData *dsdp, Eterm remote_name, Eterm message)
{
Eterm ctl;
- Eterm ctl_heap[6];
+ DeclareTmpHeapNoproc(ctl_heap,6);
Eterm token = NIL;
Process *sender = dsdp->proc;
+ int res;
+ UseTmpHeapNoproc(6);
if (SEQ_TRACE_TOKEN(sender) != NIL) {
seq_trace_update_send(sender);
token = SEQ_TRACE_TOKEN(sender);
@@ -747,7 +777,9 @@ erts_dsig_send_reg_msg(ErtsDSigData *dsdp, Eterm remote_name, Eterm message)
else
ctl = TUPLE4(&ctl_heap[0], make_small(DOP_REG_SEND),
sender->id, am_Cookie, remote_name);
- return dsig_send(dsdp, ctl, message, 0);
+ res = dsig_send(dsdp, ctl, message, 0);
+ UnUseTmpHeapNoproc(6);
+ return res;
}
/* local has died, deliver the exit signal to remote */
@@ -756,8 +788,10 @@ erts_dsig_send_exit_tt(ErtsDSigData *dsdp, Eterm local, Eterm remote,
Eterm reason, Eterm token)
{
Eterm ctl;
- Eterm ctl_heap[6];
+ DeclareTmpHeapNoproc(ctl_heap,6);
+ int res;
+ UseTmpHeapNoproc(6);
if (token != NIL) {
seq_trace_update_send(dsdp->proc);
seq_trace_output_exit(token, reason, SEQ_TRACE_SEND, remote, local);
@@ -767,38 +801,58 @@ erts_dsig_send_exit_tt(ErtsDSigData *dsdp, Eterm local, Eterm remote,
ctl = TUPLE4(&ctl_heap[0], make_small(DOP_EXIT), local, remote, reason);
}
/* forced, i.e ignore busy */
- return dsig_send(dsdp, ctl, THE_NON_VALUE, 1);
+ res = dsig_send(dsdp, ctl, THE_NON_VALUE, 1);
+ UnUseTmpHeapNoproc(6);
+ return res;
}
int
erts_dsig_send_exit(ErtsDSigData *dsdp, Eterm local, Eterm remote, Eterm reason)
{
- Eterm ctl_heap[5];
- Eterm ctl = TUPLE4(&ctl_heap[0],
- make_small(DOP_EXIT), local, remote, reason);
+ DeclareTmpHeapNoproc(ctl_heap,5);
+ int res;
+ Eterm ctl;
+
+ UseTmpHeapNoproc(5);
+ ctl = TUPLE4(&ctl_heap[0],
+ make_small(DOP_EXIT), local, remote, reason);
/* forced, i.e ignore busy */
- return dsig_send(dsdp, ctl, THE_NON_VALUE, 1);
+ res = dsig_send(dsdp, ctl, THE_NON_VALUE, 1);
+ UnUseTmpHeapNoproc(5);
+ return res;
}
int
erts_dsig_send_exit2(ErtsDSigData *dsdp, Eterm local, Eterm remote, Eterm reason)
{
- Eterm ctl_heap[5];
- Eterm ctl = TUPLE4(&ctl_heap[0],
- make_small(DOP_EXIT2), local, remote, reason);
+ DeclareTmpHeapNoproc(ctl_heap,5);
+ int res;
+ Eterm ctl;
+
+ UseTmpHeapNoproc(5);
+ ctl = TUPLE4(&ctl_heap[0],
+ make_small(DOP_EXIT2), local, remote, reason);
- return dsig_send(dsdp, ctl, THE_NON_VALUE, 0);
+ res = dsig_send(dsdp, ctl, THE_NON_VALUE, 0);
+ UnUseTmpHeapNoproc(5);
+ return res;
}
int
erts_dsig_send_group_leader(ErtsDSigData *dsdp, Eterm leader, Eterm remote)
{
- Eterm ctl_heap[4];
- Eterm ctl = TUPLE3(&ctl_heap[0],
- make_small(DOP_GROUP_LEADER), leader, remote);
+ DeclareTmpHeapNoproc(ctl_heap,4);
+ int res;
+ Eterm ctl;
- return dsig_send(dsdp, ctl, THE_NON_VALUE, 0);
+ UseTmpHeapNoproc(4);
+ ctl = TUPLE3(&ctl_heap[0],
+ make_small(DOP_GROUP_LEADER), leader, remote);
+
+ res = dsig_send(dsdp, ctl, THE_NON_VALUE, 0);
+ UnUseTmpHeapNoproc(4);
+ return res;
}
#if defined(PURIFY)
@@ -832,6 +886,7 @@ erts_dsig_send_group_leader(ErtsDSigData *dsdp, Eterm leader, Eterm remote)
**
** assert hlen == 0 !!!
*/
+
int erts_net_message(Port *prt,
DistEntry *dep,
byte *hbuf,
@@ -839,6 +894,7 @@ int erts_net_message(Port *prt,
byte *buf,
int len)
{
+#define DIST_CTL_DEFAULT_SIZE 64
ErtsDistExternal ede;
byte *t;
Sint ctl_len;
@@ -850,7 +906,7 @@ int erts_net_message(Port *prt,
Eterm *tuple;
Eterm reason;
Process* rp;
- Eterm ctl_default[64];
+ DeclareTmpHeapNoproc(ctl_default,DIST_CTL_DEFAULT_SIZE);
Eterm* ctl = ctl_default;
ErlOffHeap off_heap;
Eterm* hp;
@@ -864,6 +920,7 @@ int erts_net_message(Port *prt,
int orig_len = len;
#endif
+ UseTmpHeapNoproc(DIST_CTL_DEFAULT_SIZE);
/* Thanks to Luke Gorrie */
off_heap.mso = NULL;
#ifndef HYBRID /* FIND ME! */
@@ -876,12 +933,16 @@ int erts_net_message(Port *prt,
ERTS_SMP_LC_ASSERT(erts_lc_is_port_locked(prt));
- if (!erts_is_alive)
+ if (!erts_is_alive) {
+ UnUseTmpHeapNoproc(DIST_CTL_DEFAULT_SIZE);
return 0;
+ }
if (hlen > 0)
goto data_error;
- if (len == 0) /* HANDLE TICK !!! */
+ if (len == 0) { /* HANDLE TICK !!! */
+ UnUseTmpHeapNoproc(DIST_CTL_DEFAULT_SIZE);
return 0;
+ }
#ifdef ERTS_RAW_DIST_MSG_DBG
erts_fprintf(stderr, "<< ");
@@ -922,7 +983,8 @@ int erts_net_message(Port *prt,
goto data_error;
}
orig_ctl_len = ctl_len;
- if (ctl_len > sizeof(ctl_default)/sizeof(ctl_default[0])) {
+
+ if (ctl_len > DIST_CTL_DEFAULT_SIZE) {
ctl = erts_alloc(ERTS_ALC_T_DCTRL_BUF, ctl_len * sizeof(Eterm));
}
hp = ctl;
@@ -1202,7 +1264,7 @@ int erts_net_message(Port *prt,
{DOP_MONITOR_P_EXIT, Remote pid or name, Local pid, ref, reason} */
- Eterm lhp[3];
+ DeclareTmpHeapNoproc(lhp,3);
Eterm sysname;
ErtsProcLocks rp_locks = ERTS_PROC_LOCKS_MSG_SEND|ERTS_PROC_LOCK_LINK;
@@ -1237,6 +1299,7 @@ int erts_net_message(Port *prt,
erts_smp_proc_unlock(rp, rp_locks);
break;
}
+ UseTmpHeapNoproc(3);
watched = (is_not_nil(mon->name)
? TUPLE2(&lhp[0], mon->name, sysname)
@@ -1246,6 +1309,7 @@ int erts_net_message(Port *prt,
ref, am_process, watched, reason);
erts_smp_proc_unlock(rp, rp_locks);
erts_destroy_monitor(mon);
+ UnUseTmpHeapNoproc(3);
break;
}
@@ -1384,6 +1448,7 @@ int erts_net_message(Port *prt,
erts_free(ERTS_ALC_T_DCTRL_BUF, (void *) ctl);
}
#endif
+ UnUseTmpHeapNoproc(DIST_CTL_DEFAULT_SIZE);
ERTS_SMP_CHK_NO_PROC_LOCKS;
return 0;
@@ -1402,6 +1467,7 @@ int erts_net_message(Port *prt,
erts_free(ERTS_ALC_T_DCTRL_BUF, (void *) ctl);
}
#endif
+ UnUseTmpHeapNoproc(DIST_CTL_DEFAULT_SIZE);
erts_do_exit_port(prt, dep->cid, am_killed);
ERTS_SMP_CHK_NO_PROC_LOCKS;
return -1;
@@ -1554,9 +1620,9 @@ dsig_send(ErtsDSigData *dsdp, Eterm ctl, Eterm msg, int force_busy)
*/
data_size >>= (10-4);
-#if defined(ARCH_64)
+#if defined(ARCH_64) && !HALFWORD_HEAP
data_size &= 0x003fffffffffffff;
-#elif defined(ARCH_32)
+#elif defined(ARCH_32) || HALFWORD_HEAP
data_size &= 0x003fffff;
#else
# error "Ohh come on ... !?!"
@@ -1640,9 +1706,9 @@ dist_port_commandv(Port *prt, ErtsDistOutputBuf *obuf)
}
-#if defined(ARCH_64)
+#if defined(ARCH_64) && !HALFWORD_HEAP
#define ERTS_PORT_REDS_MASK__ 0x003fffffffffffffL
-#elif defined(ARCH_32)
+#elif defined(ARCH_32) || HALFWORD_HEAP
#define ERTS_PORT_REDS_MASK__ 0x003fffff
#else
# error "Ohh come on ... !?!"
@@ -2547,12 +2613,15 @@ BIF_RETTYPE nodes_1(BIF_ALIST_1)
int visible = 0;
int hidden = 0;
int this = 0;
- Uint buf[2]; /* For one cons-cell */
+ DeclareTmpHeap(buf,2,BIF_P); /* For one cons-cell */
DistEntry *dep;
Eterm arg_list = BIF_ARG_1;
#ifdef DEBUG
Eterm* endp;
#endif
+
+ UseTmpHeap(2,BIF_P);
+
if (is_atom(BIF_ARG_1))
arg_list = CONS(buf, BIF_ARG_1, NIL);
@@ -2563,13 +2632,14 @@ BIF_RETTYPE nodes_1(BIF_ALIST_1)
case am_known: visible = hidden = not_connected = this = 1; break;
case am_this: this = 1; break;
case am_connected: visible = hidden = 1; break;
- default: BIF_ERROR(BIF_P, BADARG); break;
+ default: goto error; break;
}
arg_list = CDR(list_val(arg_list));
}
- if (is_not_nil(arg_list))
- BIF_ERROR(BIF_P, BADARG);
+ if (is_not_nil(arg_list)) {
+ goto error;
+ }
length = 0;
@@ -2591,7 +2661,7 @@ BIF_RETTYPE nodes_1(BIF_ALIST_1)
if (length == 0) {
erts_smp_rwmtx_rwunlock(&erts_dist_table_rwmtx);
- BIF_RET(result);
+ goto done;
}
hp = HAlloc(BIF_P, 2*length);
@@ -2620,7 +2690,14 @@ BIF_RETTYPE nodes_1(BIF_ALIST_1)
}
ASSERT(endp == hp);
erts_smp_rwmtx_rwunlock(&erts_dist_table_rwmtx);
+
+done:
+ UnUseTmpHeap(2,BIF_P);
BIF_RET(result);
+
+error:
+ UnUseTmpHeap(2,BIF_P);
+ BIF_ERROR(BIF_P,BADARG);
}
/**********************************************************************/
diff --git a/erts/emulator/beam/dist.h b/erts/emulator/beam/dist.h
index ea1abcaeed..fa19c7fb45 100644
--- a/erts/emulator/beam/dist.h
+++ b/erts/emulator/beam/dist.h
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1996-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1996-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -287,4 +287,5 @@ extern void erts_kill_dist_connection(DistEntry *dep, Uint32);
extern Uint erts_dist_cache_size(void);
+
#endif
diff --git a/erts/emulator/beam/erl_alloc.c b/erts/emulator/beam/erl_alloc.c
index b853ec0f01..f8823b85fe 100644
--- a/erts/emulator/beam/erl_alloc.c
+++ b/erts/emulator/beam/erl_alloc.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2002-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2002-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -220,7 +220,7 @@ set_default_ll_alloc_opts(struct au_init *ip)
ip->init.util.ramv = 0;
ip->init.util.mmsbc = 0;
ip->init.util.mmmbc = 0;
- ip->init.util.sbct = ~((Uint) 0);
+ ip->init.util.sbct = ~((UWord) 0);
ip->init.util.name_prefix = "ll_";
ip->init.util.alloc_no = ERTS_ALC_A_LONG_LIVED;
#ifndef SMALL_MEMORY
@@ -394,7 +394,7 @@ static void init_thr_ix(int static_ixs);
void
erts_alloc_init(int *argc, char **argv, ErtsAllocInitOpts *eaiop)
{
- Uint extra_block_size = 0;
+ UWord extra_block_size = 0;
int i;
erts_alc_hndl_args_init_t init = {
0,
@@ -542,7 +542,6 @@ erts_alloc_init(int *argc, char **argv, ErtsAllocInitOpts *eaiop)
sys_alloc_opt(SYS_ALLOC_OPT_TRIM_THRESHOLD, init.trim_threshold);
sys_alloc_opt(SYS_ALLOC_OPT_TOP_PAD, init.top_pad);
-
if (erts_allctrs_info[ERTS_FIX_CORE_ALLOCATOR].enabled)
erts_fix_core_allocator_ix = ERTS_FIX_CORE_ALLOCATOR;
else
@@ -719,8 +718,8 @@ start_au_allocator(ErtsAlcType_t alctr_n,
init->init.util.name_prefix);
tspec->allctr = (Allctr_t **) states;
states = ((char *) states) + sizeof(Allctr_t *) * (tspec->size + 1);
- states = ((((Uint) states) & ERTS_CACHE_LINE_MASK)
- ? (void *) ((((Uint) states) & ~ERTS_CACHE_LINE_MASK)
+ states = ((((UWord) states) & ERTS_CACHE_LINE_MASK)
+ ? (void *) ((((UWord) states) & ~ERTS_CACHE_LINE_MASK)
+ ERTS_CACHE_LINE_SIZE)
: (void *) states);
tspec->allctr[0] = init->thr_spec > 0 ? (Allctr_t *) state : (Allctr_t *) NULL;
@@ -1605,12 +1604,13 @@ erts_memory(int *print_to_p, void *print_to_arg, void *proc, Eterm earg)
}
else {
- Eterm tmp_heap[2];
+ DeclareTmpHeapNoproc(tmp_heap,2);
Eterm wanted_list;
if (is_nil(earg))
return NIL;
+ UseTmpHeapNoproc(2);
if (is_not_atom(earg))
wanted_list = earg;
else {
@@ -1690,15 +1690,18 @@ erts_memory(int *print_to_p, void *print_to_arg, void *proc, Eterm earg)
atoms[length] = am_maximum;
uintps[length++] = &size.maximum;
}
- }
- else
+ } else {
+ UnUseTmpHeapNoproc(2);
return am_badarg;
+ }
break;
default:
+ UnUseTmpHeapNoproc(2);
return am_badarg;
}
wanted_list = CDR(list_val(wanted_list));
}
+ UnUseTmpHeapNoproc(2);
if (is_not_nil(wanted_list))
return am_badarg;
}
@@ -2285,8 +2288,8 @@ erts_allocator_info_term(void *proc, Eterm which_alloc, int only_sz)
SysAllocStat sas;
Eterm opts_am;
Eterm opts;
- Eterm as[4];
- Eterm ts[4];
+ Eterm as[4]; /* Ok even if !HEAP_ON_C_STACK, not really heap data on stack */
+ Eterm ts[4]; /* Ok even if !HEAP_ON_C_STACK, not really heap data on stack */
int l;
if (only_sz)
@@ -2944,9 +2947,9 @@ unsigned long erts_alc_test(unsigned long op,
#endif
-#define FENCE_SZ (3*sizeof(Uint))
+#define FENCE_SZ (3*sizeof(UWord))
-#ifdef ARCH_64
+#if defined(ARCH_64)
#define FENCE_PATTERN 0xABCDEF97ABCDEF97
#else
#define FENCE_PATTERN 0xABCDEF97
@@ -2956,7 +2959,7 @@ unsigned long erts_alc_test(unsigned long op,
#define TYPE_PATTERN_SHIFT 16
#define FIXED_FENCE_PATTERN_MASK \
- (~((Uint) (TYPE_PATTERN_MASK << TYPE_PATTERN_SHIFT)))
+ (~((UWord) (TYPE_PATTERN_MASK << TYPE_PATTERN_SHIFT)))
#define FIXED_FENCE_PATTERN \
(FENCE_PATTERN & FIXED_FENCE_PATTERN_MASK)
@@ -2967,21 +2970,60 @@ unsigned long erts_alc_test(unsigned long op,
(((P) >> TYPE_PATTERN_SHIFT) & TYPE_PATTERN_MASK)
+#ifdef ERTS_ALLOC_UTIL_HARD_DEBUG
+static void *check_memory_fence(void *ptr, Uint *size, ErtsAlcType_t n, int func);
+
+void check_allocated_block( Uint type, void *blk)
+{
+ Uint dummy;
+ check_memory_fence(blk, &dummy, ERTS_ALC_T2N(type), ERTS_ALC_O_FREE);
+}
+
+void check_allocators(void)
+{
+ int i;
+ if (!erts_initialized)
+ return;
+ for (i = ERTS_ALC_A_MIN; i <= ERTS_ALC_A_MAX; ++i) {
+ if (erts_allctrs_info[i].alloc_util) {
+ ErtsAllocatorFunctions_t *real_af = (ErtsAllocatorFunctions_t *) erts_allctrs[i].extra;
+ Allctr_t *allctr = real_af->extra;
+ Carrier_t *ct;
+#ifdef USE_THREADS
+ if (allctr->thread_safe)
+ erts_mtx_lock(&allctr->mutex);
+#endif
+
+ if (allctr->check_mbc) {
+ for (ct = allctr->mbc_list.first; ct; ct = ct->next) {
+ fprintf(stderr,"Checking allocator %d\r\n",i);
+ allctr->check_mbc(allctr,ct);
+ }
+ }
+#ifdef USE_THREADS
+ if (allctr->thread_safe)
+ erts_mtx_unlock(&allctr->mutex);
+#endif
+ }
+ }
+}
+#endif
+
static void *
set_memory_fence(void *ptr, Uint sz, ErtsAlcType_t n)
{
- Uint *ui_ptr;
- Uint pattern;
+ UWord *ui_ptr;
+ UWord pattern;
if (!ptr)
return NULL;
- ui_ptr = (Uint *) ptr;
+ ui_ptr = (UWord *) ptr;
pattern = MK_PATTERN(n);
*(ui_ptr++) = sz;
*(ui_ptr++) = pattern;
- memcpy((void *) (((char *) ui_ptr)+sz), (void *) &pattern, sizeof(Uint));
+ memcpy((void *) (((char *) ui_ptr)+sz), (void *) &pattern, sizeof(UWord));
return (void *) ui_ptr;
}
@@ -2991,14 +3033,14 @@ check_memory_fence(void *ptr, Uint *size, ErtsAlcType_t n, int func)
{
Uint sz;
Uint found_type;
- Uint pre_pattern;
- Uint post_pattern;
- Uint *ui_ptr;
+ UWord pre_pattern;
+ UWord post_pattern;
+ UWord *ui_ptr;
if (!ptr)
return NULL;
- ui_ptr = (Uint *) ptr;
+ ui_ptr = (UWord *) ptr;
pre_pattern = *(--ui_ptr);
*size = sz = *(--ui_ptr);
@@ -3011,7 +3053,7 @@ check_memory_fence(void *ptr, Uint *size, ErtsAlcType_t n, int func)
(unsigned long) ptr);
}
- memcpy((void *) &post_pattern, (void *) (((char *)ptr)+sz), sizeof(Uint));
+ memcpy((void *) &post_pattern, (void *) (((char *)ptr)+sz), sizeof(UWord));
if (post_pattern != MK_PATTERN(n)
|| pre_pattern != post_pattern) {
diff --git a/erts/emulator/beam/erl_alloc.h b/erts/emulator/beam/erl_alloc.h
index e7a203002f..3e96c76dbf 100644
--- a/erts/emulator/beam/erl_alloc.h
+++ b/erts/emulator/beam/erl_alloc.h
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2002-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2002-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -238,7 +238,7 @@ void *erts_realloc_fnf(ErtsAlcType_t type, void *ptr, Uint size)
#ifndef ERTS_CACHE_LINE_SIZE
/* Assume a cache line size of 64 bytes */
-# define ERTS_CACHE_LINE_SIZE ((Uint) 64)
+# define ERTS_CACHE_LINE_SIZE ((UWord) 64)
# define ERTS_CACHE_LINE_MASK (ERTS_CACHE_LINE_SIZE - 1)
#endif
@@ -486,9 +486,9 @@ init_##NAME##_alloc(void) \
qa_data_##NAME##__ = erts_alloc(ERTS_ALC_T_PRE_ALLOC_DATA,tot_size);\
chunk_start = (((char *) qa_data_##NAME##__) \
+ sizeof(erts_sched_pref_quick_alloc_data_t)); \
- if ((((Uint) chunk_start) & ERTS_CACHE_LINE_MASK) != ((Uint) 0)) \
+ if ((((UWord) chunk_start) & ERTS_CACHE_LINE_MASK) != ((UWord) 0)) \
chunk_start = ((char *) \
- ((((Uint) chunk_start) & ~ERTS_CACHE_LINE_MASK) \
+ ((((UWord) chunk_start) & ~ERTS_CACHE_LINE_MASK) \
+ ERTS_CACHE_LINE_SIZE)); \
qa_data_##NAME##__->chunks_mem_size = chunk_mem_size; \
qa_data_##NAME##__->start = (void *) chunk_start; \
@@ -553,7 +553,7 @@ NAME##_free(TYPE *p) \
}
#ifdef DEBUG
-#define ERTS_ALC_DBG_BLK_SZ(PTR) (*(((Uint *) (PTR)) - 2))
+#define ERTS_ALC_DBG_BLK_SZ(PTR) (*(((UWord *) (PTR)) - 2))
#endif /* #ifdef DEBUG */
#undef ERTS_ALC_INLINE
diff --git a/erts/emulator/beam/erl_alloc.types b/erts/emulator/beam/erl_alloc.types
index f701f71c7d..5d2872a4e3 100644
--- a/erts/emulator/beam/erl_alloc.types
+++ b/erts/emulator/beam/erl_alloc.types
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2003-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2003-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
@@ -138,6 +138,7 @@ type PEND_SUSPEND SHORT_LIVED PROCESSES pending_suspend
type PROC_LIST SHORT_LIVED PROCESSES proc_list
type FUN_ENTRY FIXED_SIZE CODE fun_entry
type ATOM_TXT LONG_LIVED ATOM atom_text
+type BEAM_REGISTER EHEAP PROCESSES beam_register
type HEAP EHEAP PROCESSES heap
type OLD_HEAP EHEAP PROCESSES old_heap
type HEAP_FRAG EHEAP PROCESSES heap_frag
@@ -322,6 +323,9 @@ type SSB SHORT_LIVED PROCESSES ssb
# Types used by system specific code
#
+type TEMP_TERM TEMPORARY SYSTEM temp_term
+type LL_TEMP_TERM LONG_LIVED SYSTEM ll_temp_term
+
type DRV_TAB LONG_LIVED SYSTEM drv_tab
type DRV_EV_STATE LONG_LIVED SYSTEM driver_event_state
type DRV_EV_D_STATE FIXED_SIZE SYSTEM driver_event_data_state
diff --git a/erts/emulator/beam/erl_alloc_util.c b/erts/emulator/beam/erl_alloc_util.c
index 9b7bc24c1c..8b184899c9 100644
--- a/erts/emulator/beam/erl_alloc_util.c
+++ b/erts/emulator/beam/erl_alloc_util.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2002-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2002-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -69,14 +69,14 @@ static int initialized = 0;
#if HAVE_ERTS_MSEG
-#define INV_MSEG_UNIT_MASK ((Uint) (mseg_unit_size - 1))
+#define INV_MSEG_UNIT_MASK ((UWord) (mseg_unit_size - 1))
#define MSEG_UNIT_MASK (~INV_MSEG_UNIT_MASK)
#define MSEG_UNIT_FLOOR(X) ((X) & MSEG_UNIT_MASK)
#define MSEG_UNIT_CEILING(X) MSEG_UNIT_FLOOR((X) + INV_MSEG_UNIT_MASK)
#endif
-#define INV_SYS_ALLOC_CARRIER_MASK ((Uint) (sys_alloc_carrier_size - 1))
+#define INV_SYS_ALLOC_CARRIER_MASK ((UWord) (sys_alloc_carrier_size - 1))
#define SYS_ALLOC_CARRIER_MASK (~INV_SYS_ALLOC_CARRIER_MASK)
#define SYS_ALLOC_CARRIER_FLOOR(X) ((X) & SYS_ALLOC_CARRIER_MASK)
#define SYS_ALLOC_CARRIER_CEILING(X) \
@@ -85,7 +85,7 @@ static int initialized = 0;
#undef ASSERT
#define ASSERT ASSERT_EXPR
-#define ERTS_ALCU_FLG_FAIL_REALLOC_MOVE ((Uint) 1)
+#define ERTS_ALCU_FLG_FAIL_REALLOC_MOVE ((UWord) 1)
#if 0
/* Can be useful for debugging */
@@ -114,12 +114,12 @@ static Uint mseg_unit_size;
/* Blocks ... */
-#define SBC_BLK_FTR_FLG (((Uint) 1) << 0)
-#define UNUSED1_BLK_FTR_FLG (((Uint) 1) << 1)
-#define UNUSED2_BLK_FTR_FLG (((Uint) 1) << 2)
+#define SBC_BLK_FTR_FLG (((UWord) 1) << 0)
+#define UNUSED1_BLK_FTR_FLG (((UWord) 1) << 1)
+#define UNUSED2_BLK_FTR_FLG (((UWord) 1) << 2)
#define ABLK_HDR_SZ (sizeof(Block_t))
-#define FBLK_FTR_SZ (sizeof(Uint))
+#define FBLK_FTR_SZ (sizeof(UWord))
#define UMEMSZ2BLKSZ(AP, SZ) \
(ABLK_HDR_SZ + (SZ) <= (AP)->min_block_size \
@@ -130,14 +130,14 @@ static Uint mseg_unit_size;
#define BLK2UMEM(P) ((void *) (((char *) (P)) + ABLK_HDR_SZ))
#define PREV_BLK_SZ(B) \
- ((Uint) (*(((Uint *) (B)) - 1) & SZ_MASK))
+ ((UWord) (*(((UWord *) (B)) - 1) & SZ_MASK))
#define SET_BLK_SZ_FTR(B, SZ) \
- (*((Uint *) (((char *) (B)) + (SZ) - sizeof(Uint))) = (SZ))
+ (*((UWord *) (((char *) (B)) + (SZ) - sizeof(UWord))) = (SZ))
-#define THIS_FREE_BLK_HDR_FLG (((Uint) 1) << 0)
-#define PREV_FREE_BLK_HDR_FLG (((Uint) 1) << 1)
-#define LAST_BLK_HDR_FLG (((Uint) 1) << 2)
+#define THIS_FREE_BLK_HDR_FLG (((UWord) 1) << 0)
+#define PREV_FREE_BLK_HDR_FLG (((UWord) 1) << 1)
+#define LAST_BLK_HDR_FLG (((UWord) 1) << 2)
#define SET_BLK_SZ(B, SZ) \
(ASSERT(((SZ) & FLG_MASK) == 0), \
@@ -156,11 +156,11 @@ static Uint mseg_unit_size;
(*((Block_t *) (B)) &= ~LAST_BLK_HDR_FLG)
#define SBH_THIS_FREE THIS_FREE_BLK_HDR_FLG
-#define SBH_THIS_ALLOCED ((Uint) 0)
+#define SBH_THIS_ALLOCED ((UWord) 0)
#define SBH_PREV_FREE PREV_FREE_BLK_HDR_FLG
-#define SBH_PREV_ALLOCED ((Uint) 0)
+#define SBH_PREV_ALLOCED ((UWord) 0)
#define SBH_LAST_BLK LAST_BLK_HDR_FLG
-#define SBH_NOT_LAST_BLK ((Uint) 0)
+#define SBH_NOT_LAST_BLK ((UWord) 0)
#define SET_BLK_HDR(B, Sz, F) \
(ASSERT(((Sz) & FLG_MASK) == 0), *((Block_t *) (B)) = ((Sz) | (F)))
@@ -200,7 +200,7 @@ static Uint mseg_unit_size;
((FTR) = 0)
#define IS_SBC_BLK(B) \
- (IS_PREV_BLK_FREE((B)) && (((Uint *) (B))[-1] & SBC_BLK_FTR_FLG))
+ (IS_PREV_BLK_FREE((B)) && (((UWord *) (B))[-1] & SBC_BLK_FTR_FLG))
#define IS_MBC_BLK(B) \
(!IS_SBC_BLK((B)))
@@ -211,8 +211,8 @@ static Uint mseg_unit_size;
/* Carriers ... */
-#define MSEG_CARRIER_HDR_FLAG (((Uint) 1) << 0)
-#define SBC_CARRIER_HDR_FLAG (((Uint) 1) << 1)
+#define MSEG_CARRIER_HDR_FLAG (((UWord) 1) << 0)
+#define SBC_CARRIER_HDR_FLAG (((UWord) 1) << 1)
#define SCH_SYS_ALLOC 0
#define SCH_MSEG MSEG_CARRIER_HDR_FLAG
@@ -407,18 +407,18 @@ do { \
/* Debug stuff... */
#ifdef DEBUG
-static Uint carrier_alignment;
+static UWord carrier_alignment;
#define DEBUG_SAVE_ALIGNMENT(C) \
do { \
- Uint algnmnt__ = sizeof(Unit_t) - (((Uint) (C)) % sizeof(Unit_t)); \
+ UWord algnmnt__ = sizeof(Unit_t) - (((UWord) (C)) % sizeof(Unit_t)); \
carrier_alignment = MIN(carrier_alignment, algnmnt__); \
- ASSERT(((Uint) (C)) % sizeof(Uint) == 0); \
+ ASSERT(((UWord) (C)) % sizeof(UWord) == 0); \
} while (0)
#define DEBUG_CHECK_ALIGNMENT(P) \
do { \
- ASSERT(sizeof(Unit_t) - (((Uint) (P)) % sizeof(Unit_t)) \
+ ASSERT(sizeof(Unit_t) - (((UWord) (P)) % sizeof(Unit_t)) \
>= carrier_alignment); \
- ASSERT(((Uint) (P)) % sizeof(Uint) == 0); \
+ ASSERT(((UWord) (P)) % sizeof(UWord) == 0); \
} while (0)
#else
@@ -610,7 +610,7 @@ unlink_carrier(CarrierList_t *cl, Carrier_t *crr)
}
-static Block_t *create_carrier(Allctr_t *, Uint, Uint);
+static Block_t *create_carrier(Allctr_t *, Uint, UWord);
static void destroy_carrier(Allctr_t *, Block_t *);
/* Multi block carrier alloc/realloc/free ... */
@@ -630,6 +630,11 @@ mbc_alloc_block(Allctr_t *allctr, Uint size, Uint *blk_szp)
blk = (*allctr->get_free_block)(allctr, *blk_szp, NULL, 0);
+#if HALFWORD_HEAP
+ if (!blk) {
+ blk = create_carrier(allctr, *blk_szp, CFLG_MBC|CFLG_FORCE_MSEG);
+ }
+#else
if (!blk) {
blk = create_carrier(allctr, *blk_szp, CFLG_MBC);
if (!blk) {
@@ -640,6 +645,7 @@ mbc_alloc_block(Allctr_t *allctr, Uint size, Uint *blk_szp)
CFLG_SBC|CFLG_FORCE_SIZE|CFLG_FORCE_SYS_ALLOC);
}
}
+#endif
#ifdef ERTS_ALLOC_UTIL_HARD_DEBUG
if (IS_MBC_BLK(blk)) {
@@ -656,14 +662,14 @@ static ERTS_INLINE void
mbc_alloc_finalize(Allctr_t *allctr,
Block_t *blk,
Uint org_blk_sz,
- Uint flags,
+ UWord flags,
Uint want_blk_sz,
int valid_blk_info)
{
Uint blk_sz;
Uint nxt_blk_sz;
Block_t *nxt_blk;
- Uint prev_free_flg = flags & PREV_FREE_BLK_HDR_FLG;
+ UWord prev_free_flg = flags & PREV_FREE_BLK_HDR_FLG;
ASSERT(org_blk_sz >= want_blk_sz);
ASSERT(blk);
@@ -853,7 +859,7 @@ mbc_free(Allctr_t *allctr, void *p)
}
static void *
-mbc_realloc(Allctr_t *allctr, void *p, Uint size, Uint flgs)
+mbc_realloc(Allctr_t *allctr, void *p, Uint size, UWord flgs)
{
void *new_p;
Uint old_blk_sz;
@@ -1144,7 +1150,7 @@ mbc_realloc(Allctr_t *allctr, void *p, Uint size, Uint flgs)
}
else {
Uint new_blk_sz;
- Uint new_blk_flgs;
+ UWord new_blk_flgs;
Uint prev_blk_sz;
Uint blk_cpy_sz;
@@ -1239,7 +1245,7 @@ do { \
static Block_t *
-create_carrier(Allctr_t *allctr, Uint umem_sz, Uint flags)
+create_carrier(Allctr_t *allctr, Uint umem_sz, UWord flags)
{
Block_t *blk;
Carrier_t *crr;
@@ -1283,8 +1289,8 @@ create_carrier(Allctr_t *allctr, Uint umem_sz, Uint flags)
if (crr_sz < allctr->mbc_header_size + blk_sz)
crr_sz = allctr->mbc_header_size + blk_sz;
#ifdef ERTS_ALLOC_UTIL_HARD_DEBUG
- if (sizeof(Unit_t) == sizeof(Uint))
- crr_sz += sizeof(Uint);
+ if (sizeof(Unit_t) == sizeof(UWord))
+ crr_sz += sizeof(UWord);
#endif
}
crr_sz = MSEG_UNIT_CEILING(crr_sz);
@@ -1324,8 +1330,8 @@ create_carrier(Allctr_t *allctr, Uint umem_sz, Uint flags)
&& bcrr_sz < allctr->smallest_mbc_size)
bcrr_sz = allctr->smallest_mbc_size;
#ifdef ERTS_ALLOC_UTIL_HARD_DEBUG
- if (sizeof(Unit_t) == sizeof(Uint))
- bcrr_sz += sizeof(Uint);
+ if (sizeof(Unit_t) == sizeof(UWord))
+ bcrr_sz += sizeof(UWord);
#endif
}
@@ -1360,7 +1366,7 @@ create_carrier(Allctr_t *allctr, Uint umem_sz, Uint flags)
blk = SBC2BLK(allctr, crr);
- SET_SBC_BLK_FTR(((Uint *) blk)[-1]);
+ SET_SBC_BLK_FTR(((UWord *) blk)[-1]);
SET_BLK_HDR(blk, blk_sz, SBH_THIS_ALLOCED|SBH_PREV_FREE|SBH_LAST_BLK);
link_carrier(&allctr->sbc_list, crr);
@@ -1379,13 +1385,13 @@ create_carrier(Allctr_t *allctr, Uint umem_sz, Uint flags)
blk = MBC2FBLK(allctr, crr);
#ifdef ERTS_ALLOC_UTIL_HARD_DEBUG
- if (sizeof(Unit_t) == sizeof(Uint))
- crr_sz -= sizeof(Uint);
+ if (sizeof(Unit_t) == sizeof(UWord))
+ crr_sz -= sizeof(UWord);
#endif
blk_sz = UNIT_FLOOR(crr_sz - allctr->mbc_header_size);
- SET_MBC_BLK_FTR(((Uint *) blk)[-1]);
+ SET_MBC_BLK_FTR(((UWord *) blk)[-1]);
SET_BLK_HDR(blk, blk_sz, SBH_THIS_FREE|SBH_PREV_FREE|SBH_LAST_BLK);
#ifdef ERTS_ALLOC_UTIL_HARD_DEBUG
@@ -1400,13 +1406,13 @@ create_carrier(Allctr_t *allctr, Uint umem_sz, Uint flags)
link_carrier(&allctr->mbc_list, crr);
#ifdef ERTS_ALLOC_UTIL_HARD_DEBUG
- if (sizeof(Unit_t) == sizeof(Uint))
- crr_sz += sizeof(Uint);
+ if (sizeof(Unit_t) == sizeof(UWord))
+ crr_sz += sizeof(UWord);
#endif
CHECK_1BLK_CARRIER(allctr, 0, is_mseg, crr, crr_sz, blk, blk_sz);
#ifdef ERTS_ALLOC_UTIL_HARD_DEBUG
- if (sizeof(Unit_t) == sizeof(Uint))
- crr_sz -= sizeof(Uint);
+ if (sizeof(Unit_t) == sizeof(UWord))
+ crr_sz -= sizeof(UWord);
#endif
if (allctr->creating_mbc)
(*allctr->creating_mbc)(allctr, crr);
@@ -1418,11 +1424,12 @@ create_carrier(Allctr_t *allctr, Uint umem_sz, Uint flags)
}
static Block_t *
-resize_carrier(Allctr_t *allctr, Block_t *old_blk, Uint umem_sz, Uint flags)
+resize_carrier(Allctr_t *allctr, Block_t *old_blk, Uint umem_sz, UWord flags)
{
Block_t *new_blk;
Carrier_t *new_crr, *old_crr;
- Uint create_flags, old_crr_sz, old_blk_sz, new_blk_sz, new_crr_sz;
+ UWord create_flags;
+ Uint old_crr_sz, old_blk_sz, new_blk_sz, new_crr_sz;
Uint new_bcrr_sz;
if (flags & CFLG_MBC) {
@@ -2522,7 +2529,12 @@ do_erts_alcu_alloc(ErtsAlcType_t type, void *extra, Uint size)
INC_CC(allctr->calls.this_alloc);
if (size >= allctr->sbc_threshold) {
+#if HALFWORD_HEAP
+ Block_t *blk = create_carrier(allctr, size,
+ CFLG_SBC | CFLG_FORCE_MSEG);
+#else
Block_t *blk = create_carrier(allctr, size, CFLG_SBC);
+#endif
res = blk ? BLK2UMEM(blk) : NULL;
}
else
@@ -2594,16 +2606,16 @@ erts_alcu_alloc_thr_pref(ErtsAlcType_t type, void *extra, Uint size)
Allctr_t *allctr;
void *res;
- ASSERT(sizeof(Uint) == sizeof(Allctr_t *));
+ ASSERT(sizeof(UWord) == sizeof(Allctr_t *));
ASSERT(ix > 0);
if (ix >= tspec->size)
ix = (ix % (tspec->size - 1)) + 1;
allctr = tspec->allctr[ix];
erts_mtx_lock(&allctr->mutex);
- res = do_erts_alcu_alloc(type, allctr, size + sizeof(Uint));
+ res = do_erts_alcu_alloc(type, allctr, size + sizeof(UWord));
if (res) {
*((Allctr_t **) res) = allctr;
- res = (void *) (((char *) res) + sizeof(Uint));
+ res = (void *) (((char *) res) + sizeof(UWord));
}
erts_mtx_unlock(&allctr->mutex);
DEBUG_CHECK_ALIGNMENT(res);
@@ -2681,7 +2693,7 @@ void
erts_alcu_free_thr_pref(ErtsAlcType_t type, void *unused, void *p)
{
if (p) {
- void *ptr = (void *) (((char *) p) - sizeof(Uint));
+ void *ptr = (void *) (((char *) p) - sizeof(UWord));
Allctr_t *allctr = *((Allctr_t **) ptr);
erts_mtx_lock(&allctr->mutex);
do_erts_alcu_free(type, allctr, ptr);
@@ -2698,7 +2710,7 @@ do_erts_alcu_realloc(ErtsAlcType_t type,
void *extra,
void *p,
Uint size,
- Uint flgs)
+ UWord flgs)
{
Allctr_t *allctr = (Allctr_t *) extra;
Block_t *blk;
@@ -2780,13 +2792,21 @@ do_erts_alcu_realloc(ErtsAlcType_t type,
Block_t *new_blk;
if(IS_SBC_BLK(blk)) {
do_carrier_resize:
+#if HALFWORD_HEAP
+ new_blk = resize_carrier(allctr, blk, size, CFLG_SBC | CFLG_FORCE_MSEG);
+#else
new_blk = resize_carrier(allctr, blk, size, CFLG_SBC);
+#endif
res = new_blk ? BLK2UMEM(new_blk) : NULL;
}
else if (flgs & ERTS_ALCU_FLG_FAIL_REALLOC_MOVE)
return NULL;
else {
+#if HALFWORD_HEAP
+ new_blk = create_carrier(allctr, size, CFLG_SBC | CFLG_FORCE_MSEG);
+#else
new_blk = create_carrier(allctr, size, CFLG_SBC);
+#endif
if (new_blk) {
res = BLK2UMEM(new_blk);
sys_memcpy((void *) res,
@@ -2962,7 +2982,7 @@ erts_alcu_realloc_thr_pref(ErtsAlcType_t type, void *extra, void *p, Uint size)
if (!p)
return erts_alcu_alloc_thr_pref(type, extra, size);
- ptr = (void *) (((char *) p) - sizeof(Uint));
+ ptr = (void *) (((char *) p) - sizeof(UWord));
used_allctr = *((Allctr_t **) ptr);
ix = erts_alc_get_thr_ix();
@@ -2976,32 +2996,32 @@ erts_alcu_realloc_thr_pref(ErtsAlcType_t type, void *extra, void *p, Uint size)
res = do_erts_alcu_realloc(type,
used_allctr,
ptr,
- size + sizeof(Uint),
+ size + sizeof(UWord),
(pref_allctr != used_allctr
? ERTS_ALCU_FLG_FAIL_REALLOC_MOVE
: 0));
erts_mtx_unlock(&used_allctr->mutex);
if (res) {
ASSERT(used_allctr == *((Allctr_t **) res));
- res = (void *) (((char *) res) + sizeof(Uint));
+ res = (void *) (((char *) res) + sizeof(UWord));
DEBUG_CHECK_ALIGNMENT(res);
}
else {
erts_mtx_lock(&pref_allctr->mutex);
- res = do_erts_alcu_alloc(type, pref_allctr, size + sizeof(Uint));
+ res = do_erts_alcu_alloc(type, pref_allctr, size + sizeof(UWord));
erts_mtx_unlock(&pref_allctr->mutex);
if (res) {
Block_t *blk;
size_t cpy_size;
*((Allctr_t **) res) = pref_allctr;
- res = (void *) (((char *) res) + sizeof(Uint));
+ res = (void *) (((char *) res) + sizeof(UWord));
DEBUG_CHECK_ALIGNMENT(res);
erts_mtx_lock(&used_allctr->mutex);
blk = UMEM2BLK(ptr);
- cpy_size = BLK_SZ(blk) - ABLK_HDR_SZ - sizeof(Uint);
+ cpy_size = BLK_SZ(blk) - ABLK_HDR_SZ - sizeof(UWord);
if (cpy_size > size)
cpy_size = size;
sys_memcpy(res, p, cpy_size);
@@ -3026,7 +3046,7 @@ erts_alcu_realloc_mv_thr_pref(ErtsAlcType_t type, void *extra,
if (!p)
return erts_alcu_alloc_thr_pref(type, extra, size);
- ptr = (void *) (((char *) p) - sizeof(Uint));
+ ptr = (void *) (((char *) p) - sizeof(UWord));
used_allctr = *((Allctr_t **) ptr);
ix = erts_alc_get_thr_ix();
@@ -3037,7 +3057,7 @@ erts_alcu_realloc_mv_thr_pref(ErtsAlcType_t type, void *extra,
ASSERT(used_allctr && pref_allctr);
erts_mtx_lock(&pref_allctr->mutex);
- res = do_erts_alcu_alloc(type, pref_allctr, size + sizeof(Uint));
+ res = do_erts_alcu_alloc(type, pref_allctr, size + sizeof(UWord));
if (!res) {
erts_mtx_unlock(&pref_allctr->mutex);
res = erts_alcu_realloc_thr_pref(type, extra, p, size);
@@ -3048,7 +3068,7 @@ erts_alcu_realloc_mv_thr_pref(ErtsAlcType_t type, void *extra,
Allctr_t *allctr;
*((Allctr_t **) res) = pref_allctr;
- res = (void *) (((char *) res) + sizeof(Uint));
+ res = (void *) (((char *) res) + sizeof(UWord));
DEBUG_CHECK_ALIGNMENT(res);
@@ -3061,7 +3081,7 @@ erts_alcu_realloc_mv_thr_pref(ErtsAlcType_t type, void *extra,
}
blk = UMEM2BLK(ptr);
- cpy_size = BLK_SZ(blk) - ABLK_HDR_SZ - sizeof(Uint);
+ cpy_size = BLK_SZ(blk) - ABLK_HDR_SZ - sizeof(UWord);
if (cpy_size > size)
cpy_size = size;
sys_memcpy(res, p, cpy_size);
@@ -3138,11 +3158,11 @@ erts_alcu_start(Allctr_t *allctr, AllctrInit_t *init)
if (allctr->min_block_size < ABLK_HDR_SZ)
goto error;
allctr->min_block_size = UNIT_CEILING(allctr->min_block_size
- + sizeof(Uint));
+ + sizeof(UWord));
#if HAVE_ERTS_MSEG
- if (allctr->mseg_opt.abs_shrink_th > ~((Uint) 0) / 100)
- allctr->mseg_opt.abs_shrink_th = ~((Uint) 0) / 100;
+ if (allctr->mseg_opt.abs_shrink_th > ~((UWord) 0) / 100)
+ allctr->mseg_opt.abs_shrink_th = ~((UWord) 0) / 100;
#endif
#ifdef USE_THREADS
@@ -3182,15 +3202,15 @@ erts_alcu_start(Allctr_t *allctr, AllctrInit_t *init)
allctr->mbc_header_size = (UNIT_CEILING(allctr->mbc_header_size
+ FBLK_FTR_SZ
+ ABLK_HDR_SZ
- + sizeof(Uint))
+ + sizeof(UWord))
- ABLK_HDR_SZ
- - sizeof(Uint));
+ - sizeof(UWord));
allctr->sbc_header_size = (UNIT_CEILING(sizeof(Carrier_t)
+ FBLK_FTR_SZ
+ ABLK_HDR_SZ
- + sizeof(Uint))
+ + sizeof(UWord))
- ABLK_HDR_SZ
- - sizeof(Uint));
+ - sizeof(UWord));
}
else
#endif
@@ -3208,12 +3228,21 @@ erts_alcu_start(Allctr_t *allctr, AllctrInit_t *init)
if (allctr->main_carrier_size) {
Block_t *blk;
+#if HALFWORD_HEAP
+ blk = create_carrier(allctr,
+ allctr->main_carrier_size,
+ CFLG_MBC
+ | CFLG_FORCE_SIZE
+ | CFLG_FORCE_MSEG
+ | CFLG_MAIN_CARRIER);
+#else
blk = create_carrier(allctr,
allctr->main_carrier_size,
CFLG_MBC
| CFLG_FORCE_SIZE
| CFLG_FORCE_SYS_ALLOC
| CFLG_MAIN_CARRIER);
+#endif
if (!blk)
goto error;
@@ -3409,7 +3438,7 @@ check_blk_carrier(Allctr_t *allctr, Block_t *iblk)
is_free_blk = (int) IS_FREE_BLK(blk);
if(is_free_blk) {
if (IS_NOT_LAST_BLK(blk))
- ASSERT(*((Uint *) (((char *) blk)+blk_sz-sizeof(Uint)))
+ ASSERT(*((UWord *) (((char *) blk)+blk_sz-sizeof(UWord)))
== blk_sz);
}
@@ -3417,7 +3446,7 @@ check_blk_carrier(Allctr_t *allctr, Block_t *iblk)
(*allctr->check_block)(allctr, blk, (int) is_free_blk);
if (IS_LAST_BLK(blk)) {
- carrier_end = ((char *) NXT_BLK(blk)) + sizeof(Uint);
+ carrier_end = ((char *) NXT_BLK(blk)) + sizeof(UWord);
mbc = *((Carrier_t **) NXT_BLK(blk));
prev_blk = NULL;
blk = MBC2FBLK(allctr, mbc);
@@ -3433,7 +3462,7 @@ check_blk_carrier(Allctr_t *allctr, Block_t *iblk)
ASSERT((((char *) mbc)
+ allctr->mbc_header_size
+ tot_blk_sz
- + sizeof(Uint)) == carrier_end);
+ + sizeof(UWord)) == carrier_end);
ASSERT(((char *) mbc) + CARRIER_SZ(mbc) == carrier_end);
if (allctr->check_mbc)
diff --git a/erts/emulator/beam/erl_alloc_util.h b/erts/emulator/beam/erl_alloc_util.h
index 10b11661e6..f2b951bca6 100644
--- a/erts/emulator/beam/erl_alloc_util.h
+++ b/erts/emulator/beam/erl_alloc_util.h
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2002-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2002-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -27,8 +27,8 @@
typedef struct Allctr_t_ Allctr_t;
typedef struct {
- Uint ycs;
- Uint mmc;
+ UWord ycs;
+ UWord mmc;
} AlcUInit_t;
typedef struct {
@@ -38,22 +38,22 @@ typedef struct {
int tspec;
int tpref;
int ramv;
- Uint sbct;
- Uint asbcst;
- Uint rsbcst;
- Uint rsbcmt;
- Uint rmbcmt;
- Uint mmbcs;
- Uint mmsbc;
- Uint mmmbc;
- Uint lmbcs;
- Uint smbcs;
- Uint mbcgs;
+ UWord sbct;
+ UWord asbcst;
+ UWord rsbcst;
+ UWord rsbcmt;
+ UWord rmbcmt;
+ UWord mmbcs;
+ UWord mmsbc;
+ UWord mmmbc;
+ UWord lmbcs;
+ UWord smbcs;
+ UWord mbcgs;
} AllctrInit_t;
typedef struct {
- Uint blocks;
- Uint carriers;
+ UWord blocks;
+ UWord carriers;
} AllctrSize_t;
#ifndef SMALL_MEMORY
@@ -163,19 +163,19 @@ void erts_alcu_current_size(Allctr_t *, AllctrSize_t *);
#define CEILING(X, I) ((((X) - 1)/(I) + 1)*(I))
#undef WORD_MASK
-#define INV_WORD_MASK ((Uint) (sizeof(Uint) - 1))
+#define INV_WORD_MASK ((UWord) (sizeof(UWord) - 1))
#define WORD_MASK (~INV_WORD_MASK)
#define WORD_FLOOR(X) ((X) & WORD_MASK)
#define WORD_CEILING(X) WORD_FLOOR((X) + INV_WORD_MASK)
#undef UNIT_MASK
-#define INV_UNIT_MASK ((Uint) (sizeof(Unit_t) - 1))
+#define INV_UNIT_MASK ((UWord) (sizeof(Unit_t) - 1))
#define UNIT_MASK (~INV_UNIT_MASK)
#define UNIT_FLOOR(X) ((X) & UNIT_MASK)
#define UNIT_CEILING(X) UNIT_FLOOR((X) + INV_UNIT_MASK)
-#define SZ_MASK (~((Uint) 0) << 3)
+#define SZ_MASK (~((UWord) 0) << 3)
#define FLG_MASK (~(SZ_MASK))
@@ -189,7 +189,7 @@ typedef union {char c[8]; long l; double d;} Unit_t;
typedef struct Carrier_t_ Carrier_t;
struct Carrier_t_ {
- Uint chdr;
+ UWord chdr;
Carrier_t *next;
Carrier_t *prev;
};
@@ -199,17 +199,17 @@ typedef struct {
Carrier_t *last;
} CarrierList_t;
-typedef Uint Block_t;
-typedef Uint FreeBlkFtr_t;
+typedef UWord Block_t;
+typedef UWord FreeBlkFtr_t;
typedef struct {
- Uint giga_no;
- Uint no;
+ UWord giga_no;
+ UWord no;
} CallCounter_t;
typedef struct {
- Uint no;
- Uint size;
+ UWord no;
+ UWord size;
} StatValues_t;
typedef struct {
diff --git a/erts/emulator/beam/erl_arith.c b/erts/emulator/beam/erl_arith.c
index 126ec7cc73..64fad9fe0e 100644
--- a/erts/emulator/beam/erl_arith.c
+++ b/erts/emulator/beam/erl_arith.c
@@ -41,6 +41,16 @@
# define MAX(x, y) (((x) > (y)) ? (x) : (y))
#endif
+#if !HEAP_ON_C_STACK
+# define DECLARE_TMP(VariableName,N,P) \
+ Eterm *VariableName = ((ERTS_PROC_GET_SCHDATA(P)->erl_arith_tmp_heap) + (2 * N))
+#else
+# define DECLARE_TMP(VariableName,N,P) \
+ Eterm VariableName[2]
+#endif
+# define ARG_IS_NOT_TMP(Arg,Tmp) ((Arg) != make_big((Tmp)))
+
+
static Eterm shift(Process* p, Eterm arg1, Eterm arg2, int right);
static ERTS_INLINE void maybe_shrink(Process* p, Eterm* hp, Eterm res, Uint alloc)
@@ -169,7 +179,7 @@ shift(Process* p, Eterm arg1, Eterm arg2, int right)
{
Sint i;
Sint ires;
- Eterm tmp_big1[2];
+ DECLARE_TMP(tmp_big1,0,p);
Eterm* bigp;
Uint need;
@@ -312,8 +322,8 @@ BIF_RETTYPE bnot_1(BIF_ALIST_1)
Eterm
erts_mixed_plus(Process* p, Eterm arg1, Eterm arg2)
{
- Eterm tmp_big1[2];
- Eterm tmp_big2[2];
+ DECLARE_TMP(tmp_big1,0,p);
+ DECLARE_TMP(tmp_big2,1,p);
Eterm res;
Eterm hdr;
FloatDef f1, f2;
@@ -458,8 +468,8 @@ erts_mixed_plus(Process* p, Eterm arg1, Eterm arg2)
Eterm
erts_mixed_minus(Process* p, Eterm arg1, Eterm arg2)
{
- Eterm tmp_big1[2];
- Eterm tmp_big2[2];
+ DECLARE_TMP(tmp_big1,0,p);
+ DECLARE_TMP(tmp_big2,1,p);
Eterm hdr;
Eterm res;
FloatDef f1, f2;
@@ -602,8 +612,8 @@ erts_mixed_minus(Process* p, Eterm arg1, Eterm arg2)
Eterm
erts_mixed_times(Process* p, Eterm arg1, Eterm arg2)
{
- Eterm tmp_big1[2];
- Eterm tmp_big2[2];
+ DECLARE_TMP(tmp_big1,0,p);
+ DECLARE_TMP(tmp_big2,1,p);
Eterm hdr;
Eterm res;
FloatDef f1, f2;
@@ -627,8 +637,8 @@ erts_mixed_times(Process* p, Eterm arg1, Eterm arg2)
} else if (arg2 == SMALL_ONE) {
return(arg1);
} else {
- Eterm big_res[3];
-
+ DeclareTmpHeap(big_res,3,p);
+ UseTmpHeap(3,p);
/*
* The following code is optimized for the case that
* result is small (which should be the most common case
@@ -636,6 +646,7 @@ erts_mixed_times(Process* p, Eterm arg1, Eterm arg2)
*/
res = small_times(signed_val(arg1), signed_val(arg2), big_res);
if (is_small(res)) {
+ UnUseTmpHeap(3,p);
return res;
} else {
/*
@@ -657,6 +668,7 @@ erts_mixed_times(Process* p, Eterm arg1, Eterm arg2)
if (arity > 1) {
*hp = big_res[2];
}
+ UnUseTmpHeap(3,p);
return res;
}
}
@@ -915,8 +927,8 @@ erts_mixed_div(Process* p, Eterm arg1, Eterm arg2)
Eterm
erts_int_div(Process* p, Eterm arg1, Eterm arg2)
{
- Eterm tmp_big1[2];
- Eterm tmp_big2[2];
+ DECLARE_TMP(tmp_big1,0,p);
+ DECLARE_TMP(tmp_big2,1,p);
int ires;
switch (NUMBER_CODE(arg1, arg2)) {
@@ -967,8 +979,8 @@ erts_int_div(Process* p, Eterm arg1, Eterm arg2)
Eterm
erts_int_rem(Process* p, Eterm arg1, Eterm arg2)
{
- Eterm tmp_big1[2];
- Eterm tmp_big2[2];
+ DECLARE_TMP(tmp_big1,0,p);
+ DECLARE_TMP(tmp_big2,1,p);
int ires;
switch (NUMBER_CODE(arg1, arg2)) {
@@ -979,7 +991,8 @@ erts_int_rem(Process* p, Eterm arg1, Eterm arg2)
if (arg1 != make_small(MIN_SMALL)) {
return arg1;
} else {
- Eterm tmp = small_to_big(signed_val(arg1), tmp_big1);
+ Eterm tmp;
+ tmp = small_to_big(signed_val(arg1), tmp_big1);
if ((ires = big_ucomp(tmp, arg2)) == 0) {
return SMALL_ZERO;
} else {
@@ -1013,8 +1026,8 @@ erts_int_rem(Process* p, Eterm arg1, Eterm arg2)
Eterm erts_band(Process* p, Eterm arg1, Eterm arg2)
{
- Eterm tmp_big1[2];
- Eterm tmp_big2[2];
+ DECLARE_TMP(tmp_big1,0,p);
+ DECLARE_TMP(tmp_big2,1,p);
Eterm* hp;
int need;
@@ -1041,8 +1054,8 @@ Eterm erts_band(Process* p, Eterm arg1, Eterm arg2)
Eterm erts_bor(Process* p, Eterm arg1, Eterm arg2)
{
- Eterm tmp_big1[2];
- Eterm tmp_big2[2];
+ DECLARE_TMP(tmp_big1,0,p);
+ DECLARE_TMP(tmp_big2,1,p);
Eterm* hp;
int need;
@@ -1069,8 +1082,8 @@ Eterm erts_bor(Process* p, Eterm arg1, Eterm arg2)
Eterm erts_bxor(Process* p, Eterm arg1, Eterm arg2)
{
- Eterm tmp_big1[2];
- Eterm tmp_big2[2];
+ DECLARE_TMP(tmp_big1,0,p);
+ DECLARE_TMP(tmp_big2,1,p);
Eterm* hp;
int need;
@@ -1148,8 +1161,8 @@ erts_gc_mixed_plus(Process* p, Eterm* reg, Uint live)
{
Eterm arg1;
Eterm arg2;
- Eterm tmp_big1[2];
- Eterm tmp_big2[2];
+ DECLARE_TMP(tmp_big1,0,p);
+ DECLARE_TMP(tmp_big2,1,p);
Eterm res;
Eterm hdr;
FloatDef f1, f2;
@@ -1237,10 +1250,10 @@ erts_gc_mixed_plus(Process* p, Eterm* reg, Uint live)
need_heap = BIG_NEED_SIZE(sz);
if (ERTS_NEED_GC(p, need_heap)) {
erts_garbage_collect(p, need_heap, reg, live+2);
- if (arg1 != make_big(tmp_big1)) {
+ if (ARG_IS_NOT_TMP(arg1,tmp_big1)) {
arg1 = reg[live];
}
- if (arg2 != make_big(tmp_big2)) {
+ if (ARG_IS_NOT_TMP(arg2,tmp_big2)) {
arg2 = reg[live+1];
}
}
@@ -1316,8 +1329,8 @@ erts_gc_mixed_minus(Process* p, Eterm* reg, Uint live)
{
Eterm arg1;
Eterm arg2;
- Eterm tmp_big1[2];
- Eterm tmp_big2[2];
+ DECLARE_TMP(tmp_big1,0,p);
+ DECLARE_TMP(tmp_big2,1,p);
Eterm hdr;
Eterm res;
FloatDef f1, f2;
@@ -1394,10 +1407,10 @@ erts_gc_mixed_minus(Process* p, Eterm* reg, Uint live)
need_heap = BIG_NEED_SIZE(sz);
if (ERTS_NEED_GC(p, need_heap)) {
erts_garbage_collect(p, need_heap, reg, live+2);
- if (arg1 != make_big(tmp_big1)) {
+ if (ARG_IS_NOT_TMP(arg1,tmp_big1)) {
arg1 = reg[live];
}
- if (arg2 != make_big(tmp_big2)) {
+ if (ARG_IS_NOT_TMP(arg2,tmp_big2)) {
arg2 = reg[live+1];
}
}
@@ -1482,8 +1495,8 @@ erts_gc_mixed_times(Process* p, Eterm* reg, Uint live)
{
Eterm arg1;
Eterm arg2;
- Eterm tmp_big1[2];
- Eterm tmp_big2[2];
+ DECLARE_TMP(tmp_big1,0,p);
+ DECLARE_TMP(tmp_big2,1,p);
Eterm hdr;
Eterm res;
FloatDef f1, f2;
@@ -1509,7 +1522,8 @@ erts_gc_mixed_times(Process* p, Eterm* reg, Uint live)
} else if (arg2 == SMALL_ONE) {
return(arg1);
} else {
- Eterm big_res[3];
+ DeclareTmpHeap(big_res,3,p);
+ UseTmpHeap(3,p);
/*
* The following code is optimized for the case that
@@ -1519,6 +1533,7 @@ erts_gc_mixed_times(Process* p, Eterm* reg, Uint live)
res = small_times(signed_val(arg1), signed_val(arg2),
big_res);
if (is_small(res)) {
+ UnUseTmpHeap(3,p);
return res;
} else {
/*
@@ -1546,6 +1561,7 @@ erts_gc_mixed_times(Process* p, Eterm* reg, Uint live)
if (arity > 1) {
*hp = big_res[2];
}
+ UnUseTmpHeap(3,p);
return res;
}
}
@@ -1609,17 +1625,17 @@ erts_gc_mixed_times(Process* p, Eterm* reg, Uint live)
need_heap = BIG_NEED_SIZE(sz);
if (ERTS_NEED_GC(p, need_heap)) {
erts_garbage_collect(p, need_heap, reg, live+2);
- if (arg1 != make_big(tmp_big1)) {
+ if (ARG_IS_NOT_TMP(arg1,tmp_big1)) {
arg1 = reg[live];
}
- if (arg2 != make_big(tmp_big2)) {
+ if (ARG_IS_NOT_TMP(arg2,tmp_big2)) {
arg2 = reg[live+1];
}
}
hp = p->htop;
p->htop += need_heap;
res = big_times(arg1, arg2, hp);
- trim_heap(p, hp, res);
+ trim_heap(p, hp, res);
/*
* Note that the result must be big in this case, since
@@ -1828,8 +1844,8 @@ erts_gc_int_div(Process* p, Eterm* reg, Uint live)
{
Eterm arg1;
Eterm arg2;
- Eterm tmp_big1[2];
- Eterm tmp_big2[2];
+ DECLARE_TMP(tmp_big1,0,p);
+ DECLARE_TMP(tmp_big2,1,p);
int ires;
arg1 = reg[live];
@@ -1866,10 +1882,10 @@ erts_gc_int_div(Process* p, Eterm* reg, Uint live)
need = BIG_NEED_SIZE(i-ires+1) + BIG_NEED_SIZE(i);
if (ERTS_NEED_GC(p, need)) {
erts_garbage_collect(p, need, reg, live+2);
- if (arg1 != make_big(tmp_big1)) {
+ if (ARG_IS_NOT_TMP(arg1,tmp_big1)) {
arg1 = reg[live];
}
- if (arg2 != make_big(tmp_big2)) {
+ if (ARG_IS_NOT_TMP(arg2,tmp_big2)) {
arg2 = reg[live+1];
}
}
@@ -1894,8 +1910,8 @@ erts_gc_int_rem(Process* p, Eterm* reg, Uint live)
{
Eterm arg1;
Eterm arg2;
- Eterm tmp_big1[2];
- Eterm tmp_big2[2];
+ DECLARE_TMP(tmp_big1,0,p);
+ DECLARE_TMP(tmp_big2,1,p);
int ires;
arg1 = reg[live];
@@ -1908,7 +1924,8 @@ erts_gc_int_rem(Process* p, Eterm* reg, Uint live)
if (arg1 != make_small(MIN_SMALL)) {
return arg1;
} else {
- Eterm tmp = small_to_big(signed_val(arg1), tmp_big1);
+ Eterm tmp;
+ tmp = small_to_big(signed_val(arg1), tmp_big1);
if ((ires = big_ucomp(tmp, arg2)) == 0) {
return SMALL_ZERO;
} else {
@@ -1928,10 +1945,10 @@ erts_gc_int_rem(Process* p, Eterm* reg, Uint live)
if (ERTS_NEED_GC(p, need)) {
erts_garbage_collect(p, need, reg, live+2);
- if (arg1 != make_big(tmp_big1)) {
+ if (ARG_IS_NOT_TMP(arg1,tmp_big1)) {
arg1 = reg[live];
}
- if (arg2 != make_big(tmp_big2)) {
+ if (ARG_IS_NOT_TMP(arg2,tmp_big2)) {
arg2 = reg[live+1];
}
}
@@ -1956,8 +1973,8 @@ Eterm erts_gc_##func(Process* p, Eterm* reg, Uint live) \
{ \
Eterm arg1; \
Eterm arg2; \
- Eterm tmp_big1[2]; \
- Eterm tmp_big2[2]; \
+ DECLARE_TMP(tmp_big1,0,p); \
+ DECLARE_TMP(tmp_big2,1,p); \
Eterm* hp; \
int need; \
\
diff --git a/erts/emulator/beam/erl_async.c b/erts/emulator/beam/erl_async.c
index b090564649..f2a581fdf4 100644
--- a/erts/emulator/beam/erl_async.c
+++ b/erts/emulator/beam/erl_async.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2000-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2000-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
#ifdef HAVE_CONFIG_H
@@ -390,14 +390,14 @@ int check_async_ready(void)
** async_data data to pass to invoke function
** async_free function for relase async_data in case of failure
*/
-long driver_async(ErlDrvPort ix, unsigned int* key,
+long driver_async(ErlDrvPort ix, unsigned long* key,
void (*async_invoke)(void*), void* async_data,
void (*async_free)(void*))
{
ErlAsync* a = (ErlAsync*) erts_alloc(ERTS_ALC_T_ASYNC, sizeof(ErlAsync));
Port* prt = erts_drvport2port(ix);
long id;
- unsigned int qix;
+ unsigned long qix;
if (!prt)
diff --git a/erts/emulator/beam/erl_bif_chksum.c b/erts/emulator/beam/erl_bif_chksum.c
index 445ba00ca7..06b7ffdf32 100644
--- a/erts/emulator/beam/erl_bif_chksum.c
+++ b/erts/emulator/beam/erl_bif_chksum.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2008-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2008-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -49,9 +49,9 @@ void erts_init_bif_chksum(void)
chksum_md5_2_exp.code[1] = am_atom_put("md5_trap",8);
chksum_md5_2_exp.code[2] = 2;
chksum_md5_2_exp.code[3] =
- (Eterm) em_apply_bif;
+ (BeamInstr) em_apply_bif;
chksum_md5_2_exp.code[4] =
- (Eterm) &md5_2;
+ (BeamInstr) &md5_2;
}
diff --git a/erts/emulator/beam/erl_bif_info.c b/erts/emulator/beam/erl_bif_info.c
index a34d400ed8..18cb09d8cd 100644
--- a/erts/emulator/beam/erl_bif_info.c
+++ b/erts/emulator/beam/erl_bif_info.c
@@ -59,12 +59,19 @@
/* Keep erts_system_version as a global variable for easy access from a core */
static char erts_system_version[] = ("Erlang " ERLANG_OTP_RELEASE
" (erts-" ERLANG_VERSION ")"
+#if !HEAP_ON_C_STACK && !HALFWORD_HEAP
+ " [no-c-stack-objects]"
+#endif
#ifndef OTP_RELEASE
" [source]"
#endif
#ifdef ARCH_64
+#if HALFWORD_HEAP
+ " [64-bit halfword]"
+#else
" [64-bit]"
#endif
+#endif
#ifdef ERTS_SMP
" [smp:%bpu:%bpu]"
#endif
@@ -121,7 +128,7 @@ bld_bin_list(Uint **hpp, Uint *szp, ProcBin* pb)
Eterm tuple;
for (; pb; pb = pb->next) {
- Eterm val = erts_bld_uint(hpp, szp, (Uint) pb->val);
+ Eterm val = erts_bld_uword(hpp, szp, (UWord) pb->val);
Eterm orig_size = erts_bld_uint(hpp, szp, pb->val->orig_size);
if (szp)
@@ -624,12 +631,18 @@ static Eterm pi_1_keys[] = {
#define ERTS_PI_1_NO_OF_KEYS (sizeof(pi_1_keys)/sizeof(Eterm))
static Eterm pi_1_keys_list;
-static Uint pi_1_keys_list_heap[2*ERTS_PI_1_NO_OF_KEYS];
+#if HEAP_ON_C_STACK
+static Eterm pi_1_keys_list_heap[2*ERTS_PI_1_NO_OF_KEYS];
+#endif
static void
process_info_init(void)
{
+#if HEAP_ON_C_STACK
Eterm *hp = &pi_1_keys_list_heap[0];
+#else
+ Eterm *hp = erts_alloc(ERTS_ALC_T_LL_TEMP_TERM,sizeof(Eterm)*2*ERTS_PI_1_NO_OF_KEYS);
+#endif
int i;
pi_1_keys_list = NIL;
@@ -998,7 +1011,7 @@ process_info_aux(Process *BIF_P,
hp = HAlloc(BIF_P, 3);
res = am_undefined;
} else {
- Eterm* current;
+ BeamInstr* current;
if (rp->current[0] == am_erlang &&
rp->current[1] == am_process_info &&
@@ -1622,6 +1635,14 @@ info_1_tuple(Process* BIF_P, /* Pointer to current process. */
if (sel == am_allocator_sizes && arity == 2) {
return erts_allocator_info_term(BIF_P, *tp, 1);
+ } else if (sel == am_wordsize && arity == 2) {
+ if (tp[0] == am_internal) {
+ return make_small(sizeof(Eterm));
+ }
+ if (tp[0] == am_external) {
+ return make_small(sizeof(UWord));
+ }
+ goto badarg;
} else if (sel == am_allocated) {
if (arity == 2) {
Eterm res = THE_NON_VALUE;
@@ -2817,7 +2838,7 @@ fun_info_2(Process* p, Eterm fun, Eterm what)
goto error;
}
} else if (is_export(fun)) {
- Export* exp = (Export *) (export_val(fun))[1];
+ Export* exp = (Export *) ((UWord) (export_val(fun))[1]);
switch (what) {
case am_type:
hp = HAlloc(p, 3);
@@ -3010,11 +3031,11 @@ BIF_RETTYPE statistics_1(BIF_ALIST_1)
res = erts_run_queues_len(NULL);
BIF_RET(make_small(res));
} else if (BIF_ARG_1 == am_wall_clock) {
- Uint w1, w2;
+ UWord w1, w2;
Eterm b1, b2;
wall_clock_elapsed_time_both(&w1, &w2);
- b1 = erts_make_integer(w1,BIF_P);
- b2 = erts_make_integer(w2,BIF_P);
+ b1 = erts_make_integer((Uint) w1,BIF_P);
+ b2 = erts_make_integer((Uint) w2,BIF_P);
hp = HAlloc(BIF_P,3);
res = TUPLE2(hp, b1, b2);
BIF_RET(res);
diff --git a/erts/emulator/beam/erl_bif_lists.c b/erts/emulator/beam/erl_bif_lists.c
index a9e8dd86f7..ce13469801 100644
--- a/erts/emulator/beam/erl_bif_lists.c
+++ b/erts/emulator/beam/erl_bif_lists.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1999-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1999-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -89,13 +89,14 @@ BIF_RETTYPE append_2(BIF_ALIST_2)
BIF_RET(copy);
}
+#define SMALL_VEC_SIZE 10
BIF_RETTYPE subtract_2(BIF_ALIST_2)
{
Eterm list;
Eterm* hp;
Uint need;
Eterm res;
- Eterm small_vec[10]; /* Preallocated memory for small lists */
+ Eterm small_vec[SMALL_VEC_SIZE]; /* Preallocated memory for small lists */
Eterm* vec_p;
Eterm* vp;
int i;
@@ -115,7 +116,7 @@ BIF_RETTYPE subtract_2(BIF_ALIST_2)
BIF_RET(BIF_ARG_1);
/* allocate element vector */
- if (n <= sizeof(small_vec)/sizeof(small_vec[0]))
+ if (n <= SMALL_VEC_SIZE)
vec_p = small_vec;
else
vec_p = (Eterm*) erts_alloc(ERTS_ALC_T_TMP, n * sizeof(Eterm));
diff --git a/erts/emulator/beam/erl_bif_op.c b/erts/emulator/beam/erl_bif_op.c
index 6da72dcef9..deda7adc1f 100644
--- a/erts/emulator/beam/erl_bif_op.c
+++ b/erts/emulator/beam/erl_bif_op.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1999-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1999-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -251,7 +251,7 @@ BIF_RETTYPE is_function_2(BIF_ALIST_2)
BIF_RET(am_true);
}
} else if (is_export(BIF_ARG_1)) {
- Export* exp = (Export *) (export_val(BIF_ARG_1))[1];
+ Export* exp = (Export *) EXPAND_POINTER((export_val(BIF_ARG_1))[1]);
if (exp->code[2] == (Uint) arity) {
BIF_RET(am_true);
diff --git a/erts/emulator/beam/erl_bif_port.c b/erts/emulator/beam/erl_bif_port.c
index f454f2e12d..0389177fbe 100644
--- a/erts/emulator/beam/erl_bif_port.c
+++ b/erts/emulator/beam/erl_bif_port.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2001-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2001-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -716,15 +716,17 @@ open_port(Process* p, Eterm name, Eterm settings, int *err_nump)
}
} else if (option == am_cd) {
Eterm iolist;
- Eterm heap[4];
+ DeclareTmpHeap(heap,4,p);
int r;
+ UseTmpHeap(4,p);
heap[0] = *tp;
heap[1] = make_list(heap+2);
heap[2] = make_small(0);
heap[3] = NIL;
iolist = make_list(heap);
r = io_list_to_buf(iolist, (char*) dir, MAXPATHLEN);
+ UnUseTmpHeap(4,p);
if (r < 0) {
goto badarg;
}
diff --git a/erts/emulator/beam/erl_bif_re.c b/erts/emulator/beam/erl_bif_re.c
index c027cd5984..d4a8a3aaa7 100644
--- a/erts/emulator/beam/erl_bif_re.c
+++ b/erts/emulator/beam/erl_bif_re.c
@@ -76,8 +76,8 @@ void erts_init_bif_re(void)
re_exec_trap_export.code[0] = am_erlang;
re_exec_trap_export.code[1] = am_re_run_trap;
re_exec_trap_export.code[2] = 3;
- re_exec_trap_export.code[3] = (Eterm) em_apply_bif;
- re_exec_trap_export.code[4] = (Eterm) &re_exec_trap;
+ re_exec_trap_export.code[3] = (BeamInstr) em_apply_bif;
+ re_exec_trap_export.code[4] = (BeamInstr) &re_exec_trap;
grun_trap_exportp = erts_export_put(am_re,am_grun,3);
urun_trap_exportp = erts_export_put(am_re,am_urun,3);
@@ -103,7 +103,7 @@ Sint erts_re_set_loop_limit(Sint limit)
static int term_to_int(Eterm term, int *sp)
{
-#ifdef ARCH_64
+#if defined(ARCH_64) && !HALFWORD_HEAP
if (is_small(term)) {
Uint x = signed_val(term);
@@ -154,7 +154,7 @@ static int term_to_int(Eterm term, int *sp)
static Eterm make_signed_integer(int x, Process *p)
{
-#ifdef ARCH_64
+#if defined(ARCH_64) && !HALFWORD_HEAP
return make_small(x);
#else
Eterm* hp;
diff --git a/erts/emulator/beam/erl_bif_timer.c b/erts/emulator/beam/erl_bif_timer.c
index 172bb37952..eb40c75110 100644
--- a/erts/emulator/beam/erl_bif_timer.c
+++ b/erts/emulator/beam/erl_bif_timer.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2005-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2005-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -155,7 +155,7 @@ create_ref(Uint *hp, Uint32 *ref_numbers, Uint32 len)
erl_exit(1, "%s:%d: Internal error\n", __FILE__, __LINE__);
}
-#ifdef ARCH_64
+#if defined(ARCH_64) && !HALFWORD_HEAP
hp[0] = make_ref_thing_header(len/2 + 1);
datap = (Uint32 *) &hp[1];
*(datap++) = len;
@@ -173,13 +173,13 @@ create_ref(Uint *hp, Uint32 *ref_numbers, Uint32 len)
static int
eq_non_standard_ref_numbers(Uint32 *rn1, Uint32 len1, Uint32 *rn2, Uint32 len2)
{
-#ifdef ARCH_64
+#if defined(ARCH_64) && !HALFWORD_HEAP
#define MAX_REF_HEAP_SZ (1+(ERTS_MAX_REF_NUMBERS/2+1))
#else
#define MAX_REF_HEAP_SZ (1+ERTS_MAX_REF_NUMBERS)
#endif
- Uint r1_hp[MAX_REF_HEAP_SZ];
- Uint r2_hp[MAX_REF_HEAP_SZ];
+ DeclareTmpHeapNoproc(r1_hp,(MAX_REF_HEAP_SZ * 2));
+ Eterm *r2_hp = r1_hp +MAX_REF_HEAP_SZ;
return eq(create_ref(r1_hp, rn1, len1), create_ref(r2_hp, rn2, len2));
#undef MAX_REF_HEAP_SZ
@@ -398,7 +398,7 @@ setup_bif_timer(Uint32 xflags,
if (!term_to_Uint(time, &timeout))
return THE_NON_VALUE;
-#ifdef ARCH_64
+#if defined(ARCH_64) && !HALFWORD_HEAP
if ((timeout >> 32) != 0)
return THE_NON_VALUE;
#endif
diff --git a/erts/emulator/beam/erl_bif_trace.c b/erts/emulator/beam/erl_bif_trace.c
index 7dff5e0eeb..7fe4410e0d 100644
--- a/erts/emulator/beam/erl_bif_trace.c
+++ b/erts/emulator/beam/erl_bif_trace.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1999-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1999-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -86,7 +86,7 @@ trace_pattern_2(Process* p, Eterm MFA, Eterm Pattern)
Eterm
trace_pattern_3(Process* p, Eterm MFA, Eterm Pattern, Eterm flaglist)
{
- Eterm mfa[3];
+ DeclareTmpHeap(mfa,3,p); /* Not really heap here, but might be when setting pattern */
int i;
int matches = 0;
int specified = 0;
@@ -101,6 +101,7 @@ trace_pattern_3(Process* p, Eterm MFA, Eterm Pattern, Eterm flaglist)
erts_smp_proc_unlock(p, ERTS_PROC_LOCK_MAIN);
erts_smp_block_system(0);
+ UseTmpHeap(3,p);
/*
* Check and compile the match specification.
*/
@@ -312,7 +313,7 @@ trace_pattern_3(Process* p, Eterm MFA, Eterm Pattern, Eterm flaglist)
MatchSetUnref(match_prog_set);
done:
-
+ UnUseTmpHeap(3,p);
erts_smp_release_system();
erts_smp_proc_lock(p, ERTS_PROC_LOCK_MAIN);
@@ -322,6 +323,7 @@ trace_pattern_3(Process* p, Eterm MFA, Eterm Pattern, Eterm flaglist)
MatchSetUnref(match_prog_set);
+ UnUseTmpHeap(3,p);
erts_smp_release_system();
erts_smp_proc_lock(p, ERTS_PROC_LOCK_MAIN);
BIF_ERROR(p, BADARG);
@@ -952,7 +954,7 @@ static int function_is_traced(Eterm mfa[3],
Export e;
Export* ep;
int i;
- Uint *code;
+ BeamInstr *code;
/* First look for an export entry */
e.code[0] = mfa[0];
@@ -960,12 +962,12 @@ static int function_is_traced(Eterm mfa[3],
e.code[2] = mfa[2];
if ((ep = export_get(&e)) != NULL) {
if (ep->address == ep->code+3 &&
- ep->code[3] != (Uint) em_call_error_handler) {
- if (ep->code[3] == (Uint) em_call_traced_function) {
+ ep->code[3] != (BeamInstr) em_call_error_handler) {
+ if (ep->code[3] == (BeamInstr) em_call_traced_function) {
*ms = ep->match_prog_set;
return FUNC_TRACE_GLOBAL_TRACE;
}
- if (ep->code[3] == (Uint) em_apply_bif) {
+ if (ep->code[3] == (BeamInstr) em_apply_bif) {
for (i = 0; i < BIF_SIZE; ++i) {
if (bif_export[i] == ep) {
int r = 0;
@@ -1011,7 +1013,7 @@ trace_info_func(Process* p, Eterm func_spec, Eterm key)
{
Eterm* tp;
Eterm* hp;
- Eterm mfa[3];
+ DeclareTmpHeap(mfa,3,p); /* Not really heap here, but might be when setting pattern */
Binary *ms = NULL, *ms_meta = NULL;
Sint count = 0;
Eterm traced = am_false;
@@ -1020,6 +1022,9 @@ trace_info_func(Process* p, Eterm func_spec, Eterm key)
Eterm meta = am_false;
int r;
+
+ UseTmpHeap(3,p);
+
if (!is_tuple(func_spec)) {
goto error;
}
@@ -1037,9 +1042,11 @@ trace_info_func(Process* p, Eterm func_spec, Eterm key)
r = function_is_traced(mfa, &ms, &ms_meta, &meta, &count);
switch (r) {
case FUNC_TRACE_NOEXIST:
+ UnUseTmpHeap(3,p);
hp = HAlloc(p, 3);
return TUPLE2(hp, key, am_undefined);
case FUNC_TRACE_UNTRACED:
+ UnUseTmpHeap(3,p);
hp = HAlloc(p, 3);
return TUPLE2(hp, key, am_false);
case FUNC_TRACE_GLOBAL_TRACE:
@@ -1120,10 +1127,12 @@ trace_info_func(Process* p, Eterm func_spec, Eterm key)
default:
goto error;
}
+ UnUseTmpHeap(3,p);
hp = HAlloc(p, 3);
return TUPLE2(hp, key, retval);
error:
+ UnUseTmpHeap(3,p);
BIF_ERROR(p, BADARG);
}
@@ -1312,7 +1321,7 @@ erts_set_trace_pattern(Eterm* mfa, int specified,
if (erts_bif_trace_flags[i] & BIF_TRACE_AS_META) {
ASSERT(ExportIsBuiltIn(bif_export[i]));
erts_clear_mtrace_bif
- ((Uint *)bif_export[i]->code + 3);
+ ((BeamInstr *)bif_export[i]->code + 3);
erts_bif_trace_flags[i] &= ~BIF_TRACE_AS_META;
}
set_trace_bif(i, match_prog_set);
@@ -1341,7 +1350,7 @@ erts_set_trace_pattern(Eterm* mfa, int specified,
}
if (flags.meta) {
erts_set_mtrace_bif
- ((Uint *)bif_export[i]->code + 3,
+ ((BeamInstr *)bif_export[i]->code + 3,
meta_match_prog_set, meta_tracer_pid);
erts_bif_trace_flags[i] |= BIF_TRACE_AS_META;
erts_bif_trace_flags[i] &= ~BIF_TRACE_AS_GLOBAL;
@@ -1361,7 +1370,7 @@ erts_set_trace_pattern(Eterm* mfa, int specified,
if (flags.meta) {
if (erts_bif_trace_flags[i] & BIF_TRACE_AS_META) {
erts_clear_mtrace_bif
- ((Uint *)bif_export[i]->code + 3);
+ ((BeamInstr *)bif_export[i]->code + 3);
erts_bif_trace_flags[i] &= ~BIF_TRACE_AS_META;
}
m = 1;
@@ -1430,9 +1439,9 @@ static int
setup_func_trace(Export* ep, void* match_prog)
{
if (ep->address == ep->code+3) {
- if (ep->code[3] == (Uint) em_call_error_handler) {
+ if (ep->code[3] == (BeamInstr) em_call_error_handler) {
return 0;
- } else if (ep->code[3] == (Uint) em_call_traced_function) {
+ } else if (ep->code[3] == (BeamInstr) em_call_traced_function) {
MatchSetUnref(ep->match_prog_set);
ep->match_prog_set = match_prog;
MatchSetRef(ep->match_prog_set);
@@ -1452,8 +1461,8 @@ setup_func_trace(Export* ep, void* match_prog)
return 0;
}
- ep->code[3] = (Uint) em_call_traced_function;
- ep->code[4] = (Uint) ep->address;
+ ep->code[3] = (BeamInstr) em_call_traced_function;
+ ep->code[4] = (BeamInstr) ep->address;
ep->address = ep->code+3;
ep->match_prog_set = match_prog;
MatchSetRef(ep->match_prog_set);
@@ -1465,7 +1474,7 @@ static void setup_bif_trace(int bif_index) {
ASSERT(ExportIsBuiltIn(ep));
ASSERT(ep->code[4]);
- ep->code[4] = (Uint) bif_table[bif_index].traced;
+ ep->code[4] = (BeamInstr) bif_table[bif_index].traced;
}
static void set_trace_bif(int bif_index, void* match_prog) {
@@ -1492,9 +1501,9 @@ static int
reset_func_trace(Export* ep)
{
if (ep->address == ep->code+3) {
- if (ep->code[3] == (Uint) em_call_error_handler) {
+ if (ep->code[3] == (BeamInstr) em_call_error_handler) {
return 0;
- } else if (ep->code[3] == (Uint) em_call_traced_function) {
+ } else if (ep->code[3] == (BeamInstr) em_call_traced_function) {
ep->address = (Uint *) ep->code[4];
MatchSetUnref(ep->match_prog_set);
ep->match_prog_set = NULL;
@@ -1527,8 +1536,8 @@ static void reset_bif_trace(int bif_index) {
ASSERT(ExportIsBuiltIn(ep));
ASSERT(ep->code[4]);
ASSERT(! ep->match_prog_set);
- ASSERT(! erts_is_mtrace_bif((Uint *)ep->code+3, NULL, NULL));
- ep->code[4] = (Uint) bif_table[bif_index].f;
+ ASSERT(! erts_is_mtrace_bif((BeamInstr *)ep->code+3, NULL, NULL));
+ ep->code[4] = (BeamInstr) bif_table[bif_index].f;
}
static void clear_trace_bif(int bif_index) {
diff --git a/erts/emulator/beam/erl_binary.h b/erts/emulator/beam/erl_binary.h
index 1f948a9684..5b0b3bcec2 100644
--- a/erts/emulator/beam/erl_binary.h
+++ b/erts/emulator/beam/erl_binary.h
@@ -164,7 +164,7 @@ byte* erts_get_aligned_binary_bytes_extra(Eterm, byte**, unsigned extra);
#endif
#define ERTS_CHK_BIN_ALIGNMENT(B) \
- do { ASSERT(!(B) || (((Uint) &((Binary *)(B))->orig_bytes[0]) & ERTS_BIN_ALIGNMENT_MASK) == ((Uint) 0)) } while(0)
+ do { ASSERT(!(B) || (((UWord) &((Binary *)(B))->orig_bytes[0]) & ERTS_BIN_ALIGNMENT_MASK) == ((UWord) 0)) } while(0)
ERTS_GLB_INLINE byte* erts_get_aligned_binary_bytes(Eterm bin, byte** base_ptr);
ERTS_GLB_INLINE void erts_free_aligned_binary_bytes(byte* buf);
diff --git a/erts/emulator/beam/erl_bits.c b/erts/emulator/beam/erl_bits.c
index e4f5d50ddf..defe18c92b 100644
--- a/erts/emulator/beam/erl_bits.c
+++ b/erts/emulator/beam/erl_bits.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1999-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1999-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -255,7 +255,7 @@ erts_bs_get_integer_2(Process *p, Uint num_bits, unsigned flags, ErlBinMatchBuff
* Simply shift whole bytes into the result.
*/
switch (BYTE_OFFSET(n)) {
-#ifdef ARCH_64
+#if defined(ARCH_64) && !HALFWORD_HEAP
case 7: w = (w << 8) | *bp++;
case 6: w = (w << 8) | *bp++;
case 5: w = (w << 8) | *bp++;
@@ -360,7 +360,7 @@ erts_bs_get_integer_2(Process *p, Uint num_bits, unsigned flags, ErlBinMatchBuff
case 3:
v32 = LSB[0] + (LSB[1]<<8) + (LSB[2]<<16);
goto big_small;
-#if !defined(ARCH_64)
+#if !defined(ARCH_64) || HALFWORD_HEAP
case 4:
v32 = (LSB[0] + (LSB[1]<<8) + (LSB[2]<<16) + (LSB[3]<<24));
if (!IS_USMALL(sgn, v32)) {
diff --git a/erts/emulator/beam/erl_bits.h b/erts/emulator/beam/erl_bits.h
index e3f8e0b679..0f67733fa4 100644
--- a/erts/emulator/beam/erl_bits.h
+++ b/erts/emulator/beam/erl_bits.h
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1999-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1999-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -63,7 +63,7 @@ typedef struct erl_bin_match_struct{
#define HEADER_NUM_SLOTS(hdr) (header_arity(hdr)-sizeof(ErlBinMatchState)/sizeof(Eterm)+1)
#define make_matchstate(_Ms) make_boxed((Eterm*)(_Ms))
-#define ms_matchbuffer(_Ms) &(((ErlBinMatchState*)(_Ms - TAG_PRIMARY_BOXED))->mb)
+#define ms_matchbuffer(_Ms) &(((ErlBinMatchState*) boxed_val(_Ms))->mb)
#if defined(ERTS_SMP)
diff --git a/erts/emulator/beam/erl_db.c b/erts/emulator/beam/erl_db.c
index 15b1c6bb56..cbdaa459de 100644
--- a/erts/emulator/beam/erl_db.c
+++ b/erts/emulator/beam/erl_db.c
@@ -87,7 +87,7 @@ static union {
static struct {
union {
DbTable *tb; /* Only directly readable if slot is ALIVE */
- Uint next_free; /* (index<<2)|1 if slot is FREE */
+ UWord next_free; /* (index<<2)|1 if slot is FREE */
}u;
} *meta_main_tab;
@@ -187,7 +187,7 @@ static Eterm ms_delete_all_buff[8]; /* To compare with for deletion
static void fix_table_locked(Process* p, DbTable* tb);
static void unfix_table_locked(Process* p, DbTable* tb, db_lock_kind_t* kind);
-static void set_heir(Process* me, DbTable* tb, Eterm heir, Eterm heir_data);
+static void set_heir(Process* me, DbTable* tb, Eterm heir, UWord heir_data);
static void free_heir_data(DbTable*);
static void free_fixations_locked(DbTable *tb);
@@ -704,12 +704,13 @@ BIF_RETTYPE ets_update_element_3(BIF_ALIST_3)
int cret = DB_ERROR_BADITEM;
Eterm list;
Eterm iter;
- Eterm cell[2];
+ DeclareTmpHeap(cell,2,BIF_P);
DbUpdateHandle handle;
if ((tb = db_get_table(BIF_P, BIF_ARG_1, DB_WRITE, LCK_WRITE_REC)) == NULL) {
BIF_ERROR(BIF_P, BADARG);
}
+ UseTmpHeap(2,BIF_P);
if (!(tb->common.status & (DB_SET | DB_ORDERED_SET))) {
goto bail_out;
}
@@ -762,6 +763,7 @@ finalize:
tb->common.meth->db_finalize_dbterm(&handle);
bail_out:
+ UnUseTmpHeap(2,BIF_P);
db_unlock(tb, LCK_WRITE_REC);
switch (cret) {
@@ -794,8 +796,8 @@ BIF_RETTYPE ets_update_counter_3(BIF_ALIST_3)
Eterm* ret_list_currp = NULL;
Eterm* ret_list_prevp = NULL;
Eterm iter;
- Eterm cell[2];
- Eterm tuple[3];
+ DeclareTmpHeap(cell,5,BIF_P);
+ Eterm *tuple = cell+2;
DbUpdateHandle handle;
Uint halloc_size = 0; /* overestimated heap usage */
Eterm* htop; /* actual heap usage */
@@ -805,6 +807,9 @@ BIF_RETTYPE ets_update_counter_3(BIF_ALIST_3)
if ((tb = db_get_table(BIF_P, BIF_ARG_1, DB_WRITE, LCK_WRITE_REC)) == NULL) {
BIF_ERROR(BIF_P, BADARG);
}
+
+ UseTmpHeap(5,BIF_P);
+
if (!(tb->common.status & (DB_SET | DB_ORDERED_SET))) {
goto bail_out;
}
@@ -951,6 +956,7 @@ finalize:
tb->common.meth->db_finalize_dbterm(&handle);
bail_out:
+ UnUseTmpHeap(5,BIF_P);
db_unlock(tb, LCK_WRITE_REC);
switch (cret) {
@@ -1180,12 +1186,12 @@ BIF_RETTYPE ets_new_2(BIF_ALIST_2)
Eterm val;
Eterm ret;
Eterm heir;
- Eterm heir_data;
+ UWord heir_data;
Uint32 status;
Sint keypos;
int is_named, is_fine_locked;
int cret;
- Eterm meta_tuple[3];
+ DeclareTmpHeap(meta_tuple,3,BIF_P);
DbTableMethod* meth;
if (is_not_atom(BIF_ARG_1)) {
@@ -1200,7 +1206,7 @@ BIF_RETTYPE ets_new_2(BIF_ALIST_2)
is_named = 0;
is_fine_locked = 0;
heir = am_none;
- heir_data = am_undefined;
+ heir_data = (UWord) am_undefined;
list = BIF_ARG_2;
while(is_list(list)) {
@@ -1375,6 +1381,8 @@ BIF_RETTYPE ets_new_2(BIF_ALIST_2)
erts_smp_atomic_read(&meta_pid_to_fixed_tab->common.memory_size));
#endif
+ UseTmpHeap(3,BIF_P);
+
db_meta_lock(meta_pid_to_tab, LCK_WRITE_REC);
if (db_put_hash(meta_pid_to_tab,
TUPLE2(meta_tuple, BIF_P->id, make_small(slot)),
@@ -1383,6 +1391,8 @@ BIF_RETTYPE ets_new_2(BIF_ALIST_2)
}
db_meta_unlock(meta_pid_to_tab, LCK_WRITE_REC);
+ UnUseTmpHeap(3,BIF_P);
+
BIF_RET(ret);
}
@@ -1519,7 +1529,7 @@ BIF_RETTYPE ets_delete_1(BIF_ALIST_1)
}
if (tb->common.owner != BIF_P->id) {
- Eterm meta_tuple[3];
+ DeclareTmpHeap(meta_tuple,3,BIF_P);
/*
* The table is being deleted by a process other than its owner.
@@ -1527,6 +1537,7 @@ BIF_RETTYPE ets_delete_1(BIF_ALIST_1)
* current process will be killed (e.g. by an EXIT signal), we will
* now transfer the ownership to the current process.
*/
+ UseTmpHeap(3,BIF_P);
db_meta_lock(meta_pid_to_tab, LCK_WRITE_REC);
db_erase_bag_exact2(meta_pid_to_tab, tb->common.owner,
make_small(tb->common.slot));
@@ -1538,6 +1549,7 @@ BIF_RETTYPE ets_delete_1(BIF_ALIST_1)
TUPLE2(meta_tuple,BIF_P->id,make_small(tb->common.slot)),
0);
db_meta_unlock(meta_pid_to_tab, LCK_WRITE_REC);
+ UnUseTmpHeap(3,BIF_P);
}
/* disable inheritance */
free_heir_data(tb);
@@ -1554,9 +1566,15 @@ BIF_RETTYPE ets_delete_1(BIF_ALIST_1)
* (it looks like an continuation pointer), but that is will crash the
* emulator if this BIF is call traced.
*/
+#if HALFWORD_HEAP
+ Eterm *hp = HAlloc(BIF_P, 3);
+ hp[0] = make_pos_bignum_header(2);
+ *((UWord *) (UWord) (hp+1)) = (UWord) tb;
+#else
Eterm *hp = HAlloc(BIF_P, 2);
hp[0] = make_pos_bignum_header(1);
hp[1] = (Eterm) tb;
+#endif
BIF_TRAP1(&ets_delete_continue_exp, BIF_P, make_big(hp));
}
else {
@@ -1571,7 +1589,7 @@ BIF_RETTYPE ets_give_away_3(BIF_ALIST_3)
{
Process* to_proc = NULL;
ErtsProcLocks to_locks = ERTS_PROC_LOCK_MAIN;
- Eterm buf[5];
+ DeclareTmpHeap(buf,5,BIF_P);
Eterm to_pid = BIF_ARG_2;
Eterm from_pid;
DbTable* tb = NULL;
@@ -1593,6 +1611,7 @@ BIF_RETTYPE ets_give_away_3(BIF_ALIST_3)
goto badarg; /* or should we be idempotent? return false maybe */
}
+ UseTmpHeap(5,BIF_P);
db_meta_lock(meta_pid_to_tab, LCK_WRITE_REC);
db_erase_bag_exact2(meta_pid_to_tab, tb->common.owner,
make_small(tb->common.slot));
@@ -1610,6 +1629,7 @@ BIF_RETTYPE ets_give_away_3(BIF_ALIST_3)
TUPLE4(buf, am_ETS_TRANSFER, tb->common.id, from_pid, BIF_ARG_3),
0);
erts_smp_proc_unlock(to_proc, to_locks);
+ UnUseTmpHeap(5,BIF_P);
BIF_RET(am_true);
badarg:
@@ -1624,11 +1644,12 @@ BIF_RETTYPE ets_setopts_2(BIF_ALIST_2)
Eterm* tp;
Eterm opt;
Eterm heir = THE_NON_VALUE;
- Eterm heir_data = THE_NON_VALUE;
+ UWord heir_data = (UWord) THE_NON_VALUE;
Uint32 protection = 0;
- Eterm fakelist[2];
+ DeclareTmpHeap(fakelist,2,BIF_P);
Eterm tail;
+ UseTmpHeap(2,BIF_P);
for (tail = is_tuple(BIF_ARG_2) ? CONS(fakelist, BIF_ARG_2, NIL) : BIF_ARG_2;
is_list(tail);
tail = CDR(list_val(tail))) {
@@ -1681,9 +1702,11 @@ BIF_RETTYPE ets_setopts_2(BIF_ALIST_2)
}
db_unlock (tb,LCK_WRITE);
+ UnUseTmpHeap(2,BIF_P);
BIF_RET(am_true);
badarg:
+ UnUseTmpHeap(2,BIF_P);
if (tb != NULL) {
db_unlock(tb,LCK_WRITE);
}
@@ -1949,29 +1972,37 @@ BIF_RETTYPE ets_match_1(BIF_ALIST_1)
BIF_RETTYPE ets_match_2(BIF_ALIST_2)
{
Eterm ms;
- Eterm buff[8];
+ DeclareTmpHeap(buff,8,BIF_P);
Eterm *hp = buff;
- /*hp = HAlloc(BIF_P, 8);*/
+ Eterm res;
+
+ UseTmpHeap(8,BIF_P);
ms = CONS(hp, am_DollarDollar, NIL);
hp += 2;
ms = TUPLE3(hp, BIF_ARG_2, NIL, ms);
hp += 4;
ms = CONS(hp, ms, NIL);
- return ets_select_2(BIF_P, BIF_ARG_1, ms);
+ res = ets_select_2(BIF_P, BIF_ARG_1, ms);
+ UnUseTmpHeap(8,BIF_P);
+ return res;
}
BIF_RETTYPE ets_match_3(BIF_ALIST_3)
{
Eterm ms;
- Eterm buff[8];
+ DeclareTmpHeap(buff,8,BIF_P);
Eterm *hp = buff;
- /*hp = HAlloc(BIF_P, 8);*/
+ Eterm res;
+
+ UseTmpHeap(8,BIF_P);
ms = CONS(hp, am_DollarDollar, NIL);
hp += 2;
ms = TUPLE3(hp, BIF_ARG_2, NIL, ms);
hp += 4;
ms = CONS(hp, ms, NIL);
- return ets_select_3(BIF_P, BIF_ARG_1, ms, BIF_ARG_3);
+ res = ets_select_3(BIF_P, BIF_ARG_1, ms, BIF_ARG_3);
+ UnUseTmpHeap(8,BIF_P);
+ return res;
}
@@ -2385,29 +2416,37 @@ BIF_RETTYPE ets_match_object_1(BIF_ALIST_1)
BIF_RETTYPE ets_match_object_2(BIF_ALIST_2)
{
Eterm ms;
- Eterm buff[8];
+ DeclareTmpHeap(buff,8,BIF_P);
Eterm *hp = buff;
- /*hp = HAlloc(BIF_P, 8);*/
+ Eterm res;
+
+ UseTmpHeap(8,BIF_P);
ms = CONS(hp, am_DollarUnderscore, NIL);
hp += 2;
ms = TUPLE3(hp, BIF_ARG_2, NIL, ms);
hp += 4;
ms = CONS(hp, ms, NIL);
- return ets_select_2(BIF_P, BIF_ARG_1, ms);
+ res = ets_select_2(BIF_P, BIF_ARG_1, ms);
+ UnUseTmpHeap(8,BIF_P);
+ return res;
}
BIF_RETTYPE ets_match_object_3(BIF_ALIST_3)
{
Eterm ms;
- Eterm buff[8];
+ DeclareTmpHeap(buff,8,BIF_P);
Eterm *hp = buff;
- /*hp = HAlloc(BIF_P, 8);*/
+ Eterm res;
+
+ UseTmpHeap(8,BIF_P);
ms = CONS(hp, am_DollarUnderscore, NIL);
hp += 2;
ms = TUPLE3(hp, BIF_ARG_2, NIL, ms);
hp += 4;
ms = CONS(hp, ms, NIL);
- return ets_select_3(BIF_P, BIF_ARG_1, ms, BIF_ARG_3);
+ res = ets_select_3(BIF_P, BIF_ARG_1, ms, BIF_ARG_3);
+ UnUseTmpHeap(8,BIF_P);
+ return res;
}
/*
@@ -2558,7 +2597,7 @@ BIF_RETTYPE ets_match_spec_run_r_3(BIF_ALIST_3)
BIF_TRAP3(bif_export[BIF_ets_match_spec_run_r_3],
BIF_P,lst,BIF_ARG_2,ret);
}
- res = db_prog_match(BIF_P, mp, CAR(list_val(lst)), 0, &dummy);
+ res = db_prog_match(BIF_P, mp, CAR(list_val(lst)), NULL, 0, &dummy);
if (is_value(res)) {
sz = size_object(res);
hp = HAlloc(BIF_P, sz + 2);
@@ -2585,7 +2624,7 @@ void init_db(void)
{
DbTable init_tb;
int i;
- extern Eterm* em_apply_bif;
+ extern BeamInstr* em_apply_bif;
Eterm *hp;
unsigned bits;
size_t size;
@@ -2714,9 +2753,9 @@ void init_db(void)
ets_select_delete_continue_exp.code[1] = am_atom_put("delete_trap",11);
ets_select_delete_continue_exp.code[2] = 1;
ets_select_delete_continue_exp.code[3] =
- (Eterm) em_apply_bif;
+ (BeamInstr) em_apply_bif;
ets_select_delete_continue_exp.code[4] =
- (Eterm) &ets_select_delete_1;
+ (BeamInstr) &ets_select_delete_1;
/* Non visual BIF to trap to. */
memset(&ets_select_count_continue_exp, 0, sizeof(Export));
@@ -2726,9 +2765,9 @@ void init_db(void)
ets_select_count_continue_exp.code[1] = am_atom_put("count_trap",11);
ets_select_count_continue_exp.code[2] = 1;
ets_select_count_continue_exp.code[3] =
- (Eterm) em_apply_bif;
+ (BeamInstr) em_apply_bif;
ets_select_count_continue_exp.code[4] =
- (Eterm) &ets_select_count_1;
+ (BeamInstr) &ets_select_count_1;
/* Non visual BIF to trap to. */
memset(&ets_select_continue_exp, 0, sizeof(Export));
@@ -2738,9 +2777,9 @@ void init_db(void)
ets_select_continue_exp.code[1] = am_atom_put("select_trap",11);
ets_select_continue_exp.code[2] = 1;
ets_select_continue_exp.code[3] =
- (Eterm) em_apply_bif;
+ (BeamInstr) em_apply_bif;
ets_select_continue_exp.code[4] =
- (Eterm) &ets_select_trap_1;
+ (BeamInstr) &ets_select_trap_1;
/* Non visual BIF to trap to. */
memset(&ets_delete_continue_exp, 0, sizeof(Export));
@@ -2748,8 +2787,8 @@ void init_db(void)
ets_delete_continue_exp.code[0] = am_ets;
ets_delete_continue_exp.code[1] = am_atom_put("delete_trap",11);
ets_delete_continue_exp.code[2] = 1;
- ets_delete_continue_exp.code[3] = (Eterm) em_apply_bif;
- ets_delete_continue_exp.code[4] = (Eterm) &ets_delete_trap;
+ ets_delete_continue_exp.code[3] = (BeamInstr) em_apply_bif;
+ ets_delete_continue_exp.code[4] = (BeamInstr) &ets_delete_trap;
hp = ms_delete_all_buff;
ms_delete_all = CONS(hp, am_true, NIL);
@@ -2843,9 +2882,9 @@ static int give_away_to_heir(Process* p, DbTable* tb)
{
Process* to_proc;
ErtsProcLocks to_locks = ERTS_PROC_LOCK_MAIN;
- Eterm buf[5];
+ DeclareTmpHeap(buf,5,p);
Eterm to_pid;
- Eterm heir_data;
+ UWord heir_data;
ASSERT(tb->common.owner == p->id);
ASSERT(is_internal_pid(tb->common.heir));
@@ -2888,6 +2927,7 @@ retry:
erts_smp_proc_unlock(to_proc, to_locks);
return 0; /* heir dead and pid reused, table still mine */
}
+ UseTmpHeap(5,p);
db_meta_lock(meta_pid_to_tab, LCK_WRITE_REC);
db_erase_bag_exact2(meta_pid_to_tab, tb->common.owner,
make_small(tb->common.slot));
@@ -2899,7 +2939,7 @@ retry:
TUPLE2(buf,to_pid,make_small(tb->common.slot)),
0);
db_meta_unlock(meta_pid_to_tab, LCK_WRITE_REC);
-
+ UnUseTmpHeap(5,p);
db_unlock(tb,LCK_WRITE);
heir_data = tb->common.heir_data;
if (!is_immed(heir_data)) {
@@ -3145,7 +3185,7 @@ erts_db_process_exiting(Process *c_p, ErtsProcLocks c_p_locks)
static void fix_table_locked(Process* p, DbTable* tb)
{
DbFixation *fix;
- Eterm meta_tuple[3];
+ DeclareTmpHeap(meta_tuple,3,p);
#ifdef ERTS_SMP
erts_smp_mtx_lock(&tb->common.fixlock);
@@ -3179,12 +3219,15 @@ static void fix_table_locked(Process* p, DbTable* tb)
erts_smp_mtx_unlock(&tb->common.fixlock);
#endif
p->flags |= F_USING_DB;
+ UseTmpHeap(3,p);
db_meta_lock(meta_pid_to_fixed_tab, LCK_WRITE_REC);
if (db_put_hash(meta_pid_to_fixed_tab,
TUPLE2(meta_tuple, p->id, make_small(tb->common.slot)),
0) != DB_ERROR_NONE) {
+ UnUseTmpHeap(3,p);
erl_exit(1,"Could not insert ets metadata in safe_fixtable.");
}
+ UnUseTmpHeap(3,p);
db_meta_unlock(meta_pid_to_fixed_tab, LCK_WRITE_REC);
}
@@ -3264,7 +3307,7 @@ static void free_fixations_locked(DbTable *tb)
tb->common.fixations = NULL;
}
-static void set_heir(Process* me, DbTable* tb, Eterm heir, Eterm heir_data)
+static void set_heir(Process* me, DbTable* tb, Eterm heir, UWord heir_data)
{
tb->common.heir = heir;
if (heir == am_none) {
@@ -3285,10 +3328,13 @@ static void set_heir(Process* me, DbTable* tb, Eterm heir, Eterm heir_data)
}
if (!is_immed(heir_data)) {
- Eterm tmp[2];
+ DeclareTmpHeap(tmp,2,me);
+
+ UseTmpHeap(2,me);
/* Make a dummy 1-tuple around data to use db_get_term() */
- heir_data = (Eterm) db_get_term(&tb->common, NULL, 0,
+ heir_data = (UWord) db_get_term(&tb->common, NULL, 0,
TUPLE1(tmp,heir_data));
+ UnUseTmpHeap(2,me);
ASSERT(!is_immed(heir_data));
}
tb->common.heir_data = heir_data;
@@ -3311,10 +3357,13 @@ static BIF_RETTYPE ets_delete_trap(Process *p, Eterm cont)
{
int trap;
Eterm* ptr = big_val(cont);
- DbTable *tb = (DbTable *) ptr[1];
+ DbTable *tb = *((DbTable **) (UWord) (ptr + 1));
+#if HALFWORD_HEAP
+ ASSERT(*ptr == make_pos_bignum_header(2));
+#else
ASSERT(*ptr == make_pos_bignum_header(1));
-
+#endif
db_lock(tb, LCK_WRITE);
trap = free_table_cont(p, tb, 0, 1);
db_unlock(tb, LCK_WRITE);
diff --git a/erts/emulator/beam/erl_db_hash.c b/erts/emulator/beam/erl_db_hash.c
index 4141f9766b..124129a371 100644
--- a/erts/emulator/beam/erl_db_hash.c
+++ b/erts/emulator/beam/erl_db_hash.c
@@ -1284,7 +1284,7 @@ static int db_select_continue_hash(Process *p,
(match_res =
db_prog_match(p,mp,
make_tuple(current->dbterm.tpl),
- 0,&dummy),
+ NULL,0,&dummy),
is_value(match_res))) {
if (all_objects) {
hp = HAlloc(p, current->dbterm.size + 2);
@@ -1462,7 +1462,7 @@ static int db_select_chunk_hash(Process *p, DbTable *tbl,
if (current->hvalue != INVALID_HASH) {
match_res = db_prog_match(p,mpi.mp,
make_tuple(current->dbterm.tpl),
- 0,&dummy);
+ NULL,0,&dummy);
if (is_value(match_res)) {
if (mpi.all_objects) {
hp = HAlloc(p, current->dbterm.size + 2);
@@ -1641,7 +1641,7 @@ static int db_select_count_hash(Process *p,
if (current != NULL) {
if (current->hvalue != INVALID_HASH) {
if (db_prog_match(p, mpi.mp, make_tuple(current->dbterm.tpl),
- 0, &dummy) == am_true) {
+ NULL,0, &dummy) == am_true) {
++got;
}
--num_left;
@@ -1792,7 +1792,7 @@ static int db_select_delete_hash(Process *p,
int did_erase = 0;
if ((db_prog_match(p,mpi.mp,
make_tuple((*current)->dbterm.tpl),
- 0,&dummy)) == am_true) {
+ NULL,0,&dummy)) == am_true) {
if (NFIXED(tb) > fixated_by_me) { /* fixated by others? */
if (slot_ix != last_pseudo_delete) {
add_fixed_deletion(tb, slot_ix);
@@ -1904,7 +1904,7 @@ static int db_select_delete_continue_hash(Process *p,
else {
int did_erase = 0;
if ((db_prog_match(p,mp,make_tuple((*current)->dbterm.tpl),
- 0,&dummy)) == am_true) {
+ NULL,0,&dummy)) == am_true) {
if (NFIXED(tb) > fixated_by_me) { /* fixated by others? */
if (slot_ix != last_pseudo_delete) {
add_fixed_deletion(tb, slot_ix);
@@ -2005,7 +2005,7 @@ static int db_select_count_continue_hash(Process *p,
continue;
}
if (db_prog_match(p, mp, make_tuple(current->dbterm.tpl),
- 0,&dummy) == am_true) {
+ NULL,0,&dummy) == am_true) {
++got;
}
--num_left;
diff --git a/erts/emulator/beam/erl_db_tree.c b/erts/emulator/beam/erl_db_tree.c
index b421da591b..b6b3cabafe 100644
--- a/erts/emulator/beam/erl_db_tree.c
+++ b/erts/emulator/beam/erl_db_tree.c
@@ -443,9 +443,9 @@ void db_initialize_tree(void)
ets_select_reverse_exp.code[1] = am_reverse;
ets_select_reverse_exp.code[2] = 3;
ets_select_reverse_exp.code[3] =
- (Eterm) em_apply_bif;
+ (BeamInstr) em_apply_bif;
ets_select_reverse_exp.code[4] =
- (Eterm) &ets_select_reverse;
+ (BeamInstr) &ets_select_reverse;
return;
};
@@ -3023,7 +3023,7 @@ static int doit_select(DbTableTree *tb, TreeDbTerm *this, void *ptr,
}
ret = db_prog_match(sc->p, sc->mp,
make_tuple(this->dbterm.tpl),
- 0, &dummy);
+ NULL,0, &dummy);
if (is_value(ret)) {
Uint sz;
Eterm *hp;
@@ -3072,7 +3072,7 @@ static int doit_select_count(DbTableTree *tb, TreeDbTerm *this, void *ptr,
}
ret = db_prog_match(sc->p, sc->mp,
make_tuple(this->dbterm.tpl),
- 0, &dummy);
+ NULL,0, &dummy);
if (ret == am_true) {
++(sc->got);
}
@@ -3105,7 +3105,7 @@ static int doit_select_chunk(DbTableTree *tb, TreeDbTerm *this, void *ptr,
ret = db_prog_match(sc->p, sc->mp,
make_tuple(this->dbterm.tpl),
- 0, &dummy);
+ NULL,0, &dummy);
if (is_value(ret)) {
Uint sz;
Eterm *hp;
@@ -3158,7 +3158,7 @@ static int doit_select_delete(DbTableTree *tb, TreeDbTerm *this, void *ptr,
return 0;
ret = db_prog_match(sc->p, sc->mp,
make_tuple(this->dbterm.tpl),
- 0, &dummy);
+ NULL,0, &dummy);
if (ret == am_true) {
key = GETKEY(sc->tb, this->dbterm.tpl);
linkout_tree(sc->tb, key);
diff --git a/erts/emulator/beam/erl_db_util.c b/erts/emulator/beam/erl_db_util.c
index 8c373451fd..fd7de98ac9 100644
--- a/erts/emulator/beam/erl_db_util.c
+++ b/erts/emulator/beam/erl_db_util.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1998-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1998-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -117,6 +117,10 @@ do { \
erts_free(ERTS_ALC_T_DB_MC_STK, (Name).data); \
} while (0)
+
+#define TermWords(t) (((t) / (sizeof(UWord)/sizeof(Eterm))) + !!((t) % (sizeof(UWord)/sizeof(Eterm))))
+
+
static ERTS_INLINE Process *
get_proc(Process *cp, Uint32 cp_locks, Eterm id, Uint32 id_locks)
{
@@ -281,7 +285,7 @@ typedef struct dmc_guard_bif {
*/
DMC_DECLARE_STACK_TYPE(Eterm);
-DMC_DECLARE_STACK_TYPE(Uint);
+DMC_DECLARE_STACK_TYPE(UWord);
DMC_DECLARE_STACK_TYPE(unsigned);
@@ -382,7 +386,7 @@ cleanup_match_pseudo_process(ErtsMatchPseudoProcess *mpsp, int keep_heap)
else {
int i;
for (i = 0; i < ERTS_DEFAULT_MS_HEAP_SIZE; i++) {
-#ifdef ARCH_64
+#if defined(ARCH_64) && !HALFWORD_HEAP
mpsp->default_heap[i] = (Eterm) 0xdeadbeefdeadbeef;
#else
mpsp->default_heap[i] = (Eterm) 0xdeadbeef;
@@ -830,42 +834,42 @@ static Uint my_size_object(Eterm t);
static Eterm my_copy_struct(Eterm t, Eterm **hp, ErlOffHeap* off_heap);
/* Guard compilation */
-static void do_emit_constant(DMCContext *context, DMC_STACK_TYPE(Uint) *text,
+static void do_emit_constant(DMCContext *context, DMC_STACK_TYPE(UWord) *text,
Eterm t);
static DMCRet dmc_list(DMCContext *context,
DMCHeap *heap,
- DMC_STACK_TYPE(Uint) *text,
+ DMC_STACK_TYPE(UWord) *text,
Eterm t,
int *constant);
static DMCRet dmc_tuple(DMCContext *context,
DMCHeap *heap,
- DMC_STACK_TYPE(Uint) *text,
+ DMC_STACK_TYPE(UWord) *text,
Eterm t,
int *constant);
static DMCRet dmc_variable(DMCContext *context,
DMCHeap *heap,
- DMC_STACK_TYPE(Uint) *text,
+ DMC_STACK_TYPE(UWord) *text,
Eterm t,
int *constant);
static DMCRet dmc_fun(DMCContext *context,
DMCHeap *heap,
- DMC_STACK_TYPE(Uint) *text,
+ DMC_STACK_TYPE(UWord) *text,
Eterm t,
int *constant);
static DMCRet dmc_expr(DMCContext *context,
DMCHeap *heap,
- DMC_STACK_TYPE(Uint) *text,
+ DMC_STACK_TYPE(UWord) *text,
Eterm t,
int *constant);
static DMCRet compile_guard_expr(DMCContext *context,
DMCHeap *heap,
- DMC_STACK_TYPE(Uint) *text,
+ DMC_STACK_TYPE(UWord) *text,
Eterm t);
/* match expression subroutine */
static DMCRet dmc_one_term(DMCContext *context,
DMCHeap *heap,
DMC_STACK_TYPE(Eterm) *stack,
- DMC_STACK_TYPE(Uint) *text,
+ DMC_STACK_TYPE(UWord) *text,
Eterm c);
@@ -1185,7 +1189,7 @@ Eterm erts_match_set_run(Process *p, Binary *mpsp,
Eterm ret;
ret = db_prog_match(p, mpsp,
- (Eterm) args,
+ NIL, args,
num_args, return_flags);
#if defined(HARDDEBUG)
if (is_non_value(ret)) {
@@ -1204,6 +1208,32 @@ Eterm erts_match_set_run(Process *p, Binary *mpsp,
*/
}
+static Eterm erts_match_set_run_ets(Process *p, Binary *mpsp,
+ Eterm args, int num_args,
+ Uint32 *return_flags)
+{
+ Eterm ret;
+
+ ret = db_prog_match(p, mpsp,
+ args, NULL,
+ num_args, return_flags);
+#if defined(HARDDEBUG)
+ if (is_non_value(ret)) {
+ erts_fprintf(stderr, "Failed\n");
+ } else {
+ erts_fprintf(stderr, "Returning : %T\n", ret);
+ }
+#endif
+ return ret;
+ /* Returns
+ * THE_NON_VALUE if no match
+ * am_false if {message,false} has been called,
+ * am_true if {message,_} has not been called or
+ * if {message,true} has been called,
+ * Msg if {message,Msg} has been called.
+ */
+}
+
/*
** API Used by other erl_db modules.
*/
@@ -1245,7 +1275,7 @@ Binary *db_match_compile(Eterm *matchexpr,
{
DMCHeap heap;
DMC_STACK_TYPE(Eterm) stack;
- DMC_STACK_TYPE(Uint) text;
+ DMC_STACK_TYPE(UWord) text;
DMCContext context;
MatchProg *ret = NULL;
Eterm t;
@@ -1380,7 +1410,7 @@ restart:
/*
** There is one single top variable in the match expression
- ** iff the text is tho Uint's and the single instruction
+ ** iff the text is two Uint's and the single instruction
** is 'matchBind' or it is only a skip.
*/
context.special =
@@ -1491,8 +1521,8 @@ restart:
** A special case is when the match expression is a single binding
** (i.e '$1'), then the field single_variable is set to 1.
*/
- bp = erts_create_magic_binary(((sizeof(MatchProg) - sizeof(Uint)) +
- (DMC_STACK_NUM(text) * sizeof(Uint))),
+ bp = erts_create_magic_binary(((sizeof(MatchProg) - sizeof(UWord)) +
+ (DMC_STACK_NUM(text) * sizeof(UWord))),
erts_db_match_prog_destructor);
ret = Binary2MatchProg(bp);
ret->saved_program_buf = NULL;
@@ -1501,7 +1531,7 @@ restart:
ret->num_bindings = heap.used;
ret->single_variable = context.special;
sys_memcpy(ret->text, DMC_STACK_DATA(text),
- DMC_STACK_NUM(text) * sizeof(Uint));
+ DMC_STACK_NUM(text) * sizeof(UWord));
ret->heap_size = ((heap.used * sizeof(Eterm)) +
(max_eheap_need * sizeof(Eterm)) +
(context.stack_need * sizeof(Eterm *)) +
@@ -1591,6 +1621,7 @@ static Eterm dpm_array_to_list(Process *psp, Eterm *arr, int arity)
** i.e. 'DCOMP_TRACE' was specified
*/
Eterm db_prog_match(Process *c_p, Binary *bprog, Eterm term,
+ Eterm *termp,
int arity,
Uint32 *return_flags)
{
@@ -1601,7 +1632,8 @@ Eterm db_prog_match(Process *c_p, Binary *bprog, Eterm term,
Eterm **sp;
Eterm *esp;
Eterm *hp;
- Uint *pc = prog->text;
+ BeamInstr *cp;
+ UWord *pc = prog->text;
Eterm *ehp;
Eterm ret;
Uint n = 0; /* To avoid warning. */
@@ -1616,9 +1648,9 @@ Eterm db_prog_match(Process *c_p, Binary *bprog, Eterm term,
int fail_label;
int atomic_trace;
#ifdef DMC_DEBUG
- unsigned long *heap_fence;
- unsigned long *eheap_fence;
- unsigned long *stack_fence;
+ Uint *heap_fence;
+ Uint *eheap_fence;
+ Uint *stack_fence;
Uint save_op;
#endif /* DMC_DEBUG */
@@ -1654,9 +1686,9 @@ Eterm db_prog_match(Process *c_p, Binary *bprog, Eterm term,
#ifdef DMC_DEBUG
save_op = 0;
- heap_fence = (unsigned long *) mpsp->heap + prog->eheap_offset - 1;
- eheap_fence = (unsigned long *) mpsp->heap + prog->stack_offset - 1;
- stack_fence = (unsigned long *) mpsp->heap + prog->heap_size - 1;
+ heap_fence = (Uint *) mpsp->heap + prog->eheap_offset - 1;
+ eheap_fence = (Uint *) mpsp->heap + prog->stack_offset - 1;
+ stack_fence = (Uint *) mpsp->heap + prog->heap_size - 1;
*heap_fence = FENCE_PATTERN;
*eheap_fence = FENCE_PATTERN;
*stack_fence = FENCE_PATTERN;
@@ -1709,11 +1741,12 @@ restart:
n = *pc++;
if ((int) n != arity)
FAIL();
- ep = (Eterm *) *ep;
+ ep = termp;
break;
- case matchArrayBind: /* When the array size is unknown. */
+ case matchArrayBind: /* When the array size is unknown. */ /* XXX:PaN - where does
+ this array come from? */
n = *pc++;
- hp[n] = dpm_array_to_list(psp, (Eterm *) term, arity);
+ hp[n] = dpm_array_to_list(psp, termp, arity);
break;
case matchTuple: /* *ep is a tuple of arity n */
if (!is_tuple(*ep))
@@ -1770,29 +1803,34 @@ restart:
FAIL();
if (memcmp(float_val(*ep) + 1, pc, sizeof(double)))
FAIL();
- pc += 2;
+ pc += TermWords(2);
++ep;
break;
case matchEqRef:
if (!is_ref(*ep))
FAIL();
- if (!eq(*ep, make_internal_ref(pc)))
+ if (!eq(*ep, make_internal_ref((Uint *) pc)))
FAIL();
- i = thing_arityval(*pc);
- pc += i+1;
+ i = thing_arityval(*((Uint *) pc));
+ pc += TermWords(i+1);
++ep;
break;
case matchEqBig:
if (!is_big(*ep))
FAIL();
tp = big_val(*ep);
- if (*tp != *pc)
- FAIL();
- i = BIG_ARITY(pc);
- while(i--)
- if (*++tp != *++pc)
+ {
+ Eterm *epc = (Eterm *) pc;
+ if (*tp != *epc)
FAIL();
- ++pc;
+ i = BIG_ARITY(epc);
+ pc += TermWords(i+1);
+ while(i--) {
+ if (*++tp != *++epc) {
+ FAIL();
+ }
+ }
+ }
++ep;
break;
case matchEq:
@@ -1884,7 +1922,7 @@ restart:
break;
case matchPushArrayAsList:
n = arity; /* Only happens when 'term' is an array */
- tp = (Eterm *) term;
+ tp = termp;
*esp++ = make_list(ehp);
while (n--) {
*ehp++ = *tp++;
@@ -1897,7 +1935,7 @@ restart:
break;
case matchPushArrayAsListU:
/* This instruction is NOT efficient. */
- *esp++ = dpm_array_to_list(psp, (Eterm *) term, arity);
+ *esp++ = dpm_array_to_list(psp, termp, arity);
break;
case matchTrue:
if (*--esp != am_true)
@@ -2095,17 +2133,17 @@ restart:
}
break;
case matchCaller:
- if (!(c_p->cp) || !(hp = find_function_from_pc(c_p->cp))) {
+ if (!(c_p->cp) || !(cp = find_function_from_pc(c_p->cp))) {
*esp++ = am_undefined;
} else {
*esp++ = make_tuple(ehp);
- ehp[0] = make_arityval(3);
- ehp[1] = hp[0];
- ehp[2] = hp[1];
- ehp[3] = make_small(hp[2]);
- ehp += 4;
- }
- break;
+ ehp[0] = make_arityval(3);
+ ehp[1] = cp[0];
+ ehp[2] = cp[1];
+ ehp[3] = make_small((Uint) cp[2]);
+ ehp += 4;
+ }
+ break;
case matchSilent:
--esp;
if (*esp == am_true) {
@@ -2300,7 +2338,7 @@ void db_free_dmc_err_info(DMCErrInfo *ei){
*/
Eterm db_add_counter(Eterm** hpp, Eterm counter, Eterm incr)
{
- Eterm big_tmp[2];
+ DeclareTmpHeapNoproc(big_tmp,2);
Eterm res;
Sint ires;
Eterm arg1;
@@ -2318,6 +2356,7 @@ Eterm db_add_counter(Eterm** hpp, Eterm counter, Eterm incr)
}
}
else {
+ UseTmpHeapNoproc(2);
switch(NUMBER_CODE(counter, incr)) {
case SMALL_BIG:
arg1 = small_to_big(signed_val(counter), big_tmp);
@@ -2332,12 +2371,14 @@ Eterm db_add_counter(Eterm** hpp, Eterm counter, Eterm incr)
arg2 = counter;
break;
default:
+ UnUseTmpHeapNoproc(2);
return THE_NON_VALUE;
}
res = big_plus(arg1, arg2, *hpp);
if (is_big(res)) {
*hpp += BIG_NEED_SIZE(big_size(res));
}
+ UnUseTmpHeapNoproc(2);
return res;
}
}
@@ -2606,7 +2647,7 @@ static void add_dmc_err(DMCErrInfo *err_info,
static DMCRet dmc_one_term(DMCContext *context,
DMCHeap *heap,
DMC_STACK_TYPE(Eterm) *stack,
- DMC_STACK_TYPE(Uint) *text,
+ DMC_STACK_TYPE(UWord) *text,
Eterm c)
{
Sint n;
@@ -2704,27 +2745,80 @@ static DMCRet dmc_one_term(DMCContext *context,
DMC_PUSH(*stack, c);
break;
case (_TAG_HEADER_REF >> _TAG_PRIMARY_SIZE):
- n = thing_arityval(*internal_ref_val(c));
DMC_PUSH(*text, matchEqRef);
+#if HALFWORD_HEAP
+ {
+ union {
+ UWord u;
+ Uint t[2];
+ } fiddle;
+ ASSERT(thing_arityval(*internal_ref_val(c)) == 3);
+ fiddle.t[0] = *internal_ref_val(c);
+ fiddle.t[1] = (Uint) internal_ref_val(c)[1];
+ DMC_PUSH(*text, fiddle.u);
+ fiddle.t[0] = (Uint) internal_ref_val(c)[2];
+ fiddle.t[1] = (Uint) internal_ref_val(c)[3];
+ DMC_PUSH(*text, fiddle.u);
+ }
+#else
+ n = thing_arityval(*internal_ref_val(c));
DMC_PUSH(*text, *internal_ref_val(c));
for (i = 1; i <= n; ++i) {
DMC_PUSH(*text, (Uint) internal_ref_val(c)[i]);
}
+#endif
break;
case (_TAG_HEADER_POS_BIG >> _TAG_PRIMARY_SIZE):
case (_TAG_HEADER_NEG_BIG >> _TAG_PRIMARY_SIZE):
n = thing_arityval(*big_val(c));
DMC_PUSH(*text, matchEqBig);
+#if HALFWORD_HEAP
+ {
+ union {
+ UWord u;
+ Uint t[2];
+ } fiddle;
+ ASSERT(n >= 1);
+ fiddle.t[0] = *big_val(c);
+ fiddle.t[1] = big_val(c)[1];
+ DMC_PUSH(*text, fiddle.u);
+ for (i = 2; i <= n; ++i) {
+ fiddle.t[0] = big_val(c)[i];
+ if (++i <= n) {
+ fiddle.t[1] = big_val(c)[i];
+ } else {
+ fiddle.t[1] = (Uint) 0;
+ }
+ DMC_PUSH(*text, fiddle.u);
+ }
+ }
+#else
DMC_PUSH(*text, *big_val(c));
for (i = 1; i <= n; ++i) {
DMC_PUSH(*text, (Uint) big_val(c)[i]);
}
+#endif
break;
case (_TAG_HEADER_FLOAT >> _TAG_PRIMARY_SIZE):
DMC_PUSH(*text,matchEqFloat);
+#if HALFWORD_HEAP
+ {
+ union {
+ UWord u;
+ Uint t[2];
+ } fiddle;
+ fiddle.t[0] = float_val(c)[1];
+ fiddle.t[1] = float_val(c)[2];
+ DMC_PUSH(*text, fiddle.u);
+ }
+#else
DMC_PUSH(*text, (Uint) float_val(c)[1]);
- /* XXX: this reads and pushes random junk on ARCH_64 */
+#ifdef ARCH_64
+ DMC_PUSH(*text, (Uint) 0);
+#else
DMC_PUSH(*text, (Uint) float_val(c)[2]);
+#endif
+#endif
break;
default: /* BINARY, FUN, VECTOR, or EXTERNAL */
/*
@@ -2753,7 +2847,7 @@ static DMCRet dmc_one_term(DMCContext *context,
** Match guard compilation
*/
-static void do_emit_constant(DMCContext *context, DMC_STACK_TYPE(Uint) *text,
+static void do_emit_constant(DMCContext *context, DMC_STACK_TYPE(UWord) *text,
Eterm t)
{
int sz;
@@ -2807,7 +2901,7 @@ add_dmc_err((ContextP)->err_info, String, -1, T, dmcWarning)
static DMCRet dmc_list(DMCContext *context,
DMCHeap *heap,
- DMC_STACK_TYPE(Uint) *text,
+ DMC_STACK_TYPE(UWord) *text,
Eterm t,
int *constant)
{
@@ -2843,11 +2937,11 @@ static DMCRet dmc_list(DMCContext *context,
static DMCRet dmc_tuple(DMCContext *context,
DMCHeap *heap,
- DMC_STACK_TYPE(Uint) *text,
+ DMC_STACK_TYPE(UWord) *text,
Eterm t,
int *constant)
{
- DMC_STACK_TYPE(Uint) instr_save;
+ DMC_STACK_TYPE(UWord) instr_save;
int all_constant = 1;
int textpos = DMC_STACK_NUM(*text);
Eterm *p = tuple_val(t);
@@ -2903,7 +2997,7 @@ static DMCRet dmc_tuple(DMCContext *context,
static DMCRet dmc_whole_expression(DMCContext *context,
DMCHeap *heap,
- DMC_STACK_TYPE(Uint) *text,
+ DMC_STACK_TYPE(UWord) *text,
Eterm t,
int *constant)
{
@@ -2931,7 +3025,7 @@ static DMCRet dmc_whole_expression(DMCContext *context,
static DMCRet dmc_variable(DMCContext *context,
DMCHeap *heap,
- DMC_STACK_TYPE(Uint) *text,
+ DMC_STACK_TYPE(UWord) *text,
Eterm t,
int *constant)
{
@@ -2952,7 +3046,7 @@ static DMCRet dmc_variable(DMCContext *context,
static DMCRet dmc_all_bindings(DMCContext *context,
DMCHeap *heap,
- DMC_STACK_TYPE(Uint) *text,
+ DMC_STACK_TYPE(UWord) *text,
Eterm t,
int *constant)
{
@@ -2979,7 +3073,7 @@ static DMCRet dmc_all_bindings(DMCContext *context,
static DMCRet dmc_const(DMCContext *context,
DMCHeap *heap,
- DMC_STACK_TYPE(Uint) *text,
+ DMC_STACK_TYPE(UWord) *text,
Eterm t,
int *constant)
{
@@ -2996,7 +3090,7 @@ static DMCRet dmc_const(DMCContext *context,
static DMCRet dmc_and(DMCContext *context,
DMCHeap *heap,
- DMC_STACK_TYPE(Uint) *text,
+ DMC_STACK_TYPE(UWord) *text,
Eterm t,
int *constant)
{
@@ -3025,7 +3119,7 @@ static DMCRet dmc_and(DMCContext *context,
static DMCRet dmc_or(DMCContext *context,
DMCHeap *heap,
- DMC_STACK_TYPE(Uint) *text,
+ DMC_STACK_TYPE(UWord) *text,
Eterm t,
int *constant)
{
@@ -3055,7 +3149,7 @@ static DMCRet dmc_or(DMCContext *context,
static DMCRet dmc_andalso(DMCContext *context,
DMCHeap *heap,
- DMC_STACK_TYPE(Uint) *text,
+ DMC_STACK_TYPE(UWord) *text,
Eterm t,
int *constant)
{
@@ -3104,7 +3198,7 @@ static DMCRet dmc_andalso(DMCContext *context,
static DMCRet dmc_orelse(DMCContext *context,
DMCHeap *heap,
- DMC_STACK_TYPE(Uint) *text,
+ DMC_STACK_TYPE(UWord) *text,
Eterm t,
int *constant)
{
@@ -3152,7 +3246,7 @@ static DMCRet dmc_orelse(DMCContext *context,
static DMCRet dmc_message(DMCContext *context,
DMCHeap *heap,
- DMC_STACK_TYPE(Uint) *text,
+ DMC_STACK_TYPE(UWord) *text,
Eterm t,
int *constant)
{
@@ -3194,7 +3288,7 @@ static DMCRet dmc_message(DMCContext *context,
static DMCRet dmc_self(DMCContext *context,
DMCHeap *heap,
- DMC_STACK_TYPE(Uint) *text,
+ DMC_STACK_TYPE(UWord) *text,
Eterm t,
int *constant)
{
@@ -3214,7 +3308,7 @@ static DMCRet dmc_self(DMCContext *context,
static DMCRet dmc_return_trace(DMCContext *context,
DMCHeap *heap,
- DMC_STACK_TYPE(Uint) *text,
+ DMC_STACK_TYPE(UWord) *text,
Eterm t,
int *constant)
{
@@ -3244,7 +3338,7 @@ static DMCRet dmc_return_trace(DMCContext *context,
static DMCRet dmc_exception_trace(DMCContext *context,
DMCHeap *heap,
- DMC_STACK_TYPE(Uint) *text,
+ DMC_STACK_TYPE(UWord) *text,
Eterm t,
int *constant)
{
@@ -3276,7 +3370,7 @@ static DMCRet dmc_exception_trace(DMCContext *context,
static DMCRet dmc_is_seq_trace(DMCContext *context,
DMCHeap *heap,
- DMC_STACK_TYPE(Uint) *text,
+ DMC_STACK_TYPE(UWord) *text,
Eterm t,
int *constant)
{
@@ -3302,7 +3396,7 @@ static DMCRet dmc_is_seq_trace(DMCContext *context,
static DMCRet dmc_set_seq_token(DMCContext *context,
DMCHeap *heap,
- DMC_STACK_TYPE(Uint) *text,
+ DMC_STACK_TYPE(UWord) *text,
Eterm t,
int *constant)
{
@@ -3351,7 +3445,7 @@ static DMCRet dmc_set_seq_token(DMCContext *context,
static DMCRet dmc_get_seq_token(DMCContext *context,
DMCHeap *heap,
- DMC_STACK_TYPE(Uint) *text,
+ DMC_STACK_TYPE(UWord) *text,
Eterm t,
int *constant)
{
@@ -3388,7 +3482,7 @@ static DMCRet dmc_get_seq_token(DMCContext *context,
static DMCRet dmc_display(DMCContext *context,
DMCHeap *heap,
- DMC_STACK_TYPE(Uint) *text,
+ DMC_STACK_TYPE(UWord) *text,
Eterm t,
int *constant)
{
@@ -3428,7 +3522,7 @@ static DMCRet dmc_display(DMCContext *context,
static DMCRet dmc_process_dump(DMCContext *context,
DMCHeap *heap,
- DMC_STACK_TYPE(Uint) *text,
+ DMC_STACK_TYPE(UWord) *text,
Eterm t,
int *constant)
{
@@ -3458,7 +3552,7 @@ static DMCRet dmc_process_dump(DMCContext *context,
static DMCRet dmc_enable_trace(DMCContext *context,
DMCHeap *heap,
- DMC_STACK_TYPE(Uint) *text,
+ DMC_STACK_TYPE(UWord) *text,
Eterm t,
int *constant)
{
@@ -3518,7 +3612,7 @@ static DMCRet dmc_enable_trace(DMCContext *context,
static DMCRet dmc_disable_trace(DMCContext *context,
DMCHeap *heap,
- DMC_STACK_TYPE(Uint) *text,
+ DMC_STACK_TYPE(UWord) *text,
Eterm t,
int *constant)
{
@@ -3578,7 +3672,7 @@ static DMCRet dmc_disable_trace(DMCContext *context,
static DMCRet dmc_trace(DMCContext *context,
DMCHeap *heap,
- DMC_STACK_TYPE(Uint) *text,
+ DMC_STACK_TYPE(UWord) *text,
Eterm t,
int *constant)
{
@@ -3652,7 +3746,7 @@ static DMCRet dmc_trace(DMCContext *context,
static DMCRet dmc_caller(DMCContext *context,
DMCHeap *heap,
- DMC_STACK_TYPE(Uint) *text,
+ DMC_STACK_TYPE(UWord) *text,
Eterm t,
int *constant)
{
@@ -3685,7 +3779,7 @@ static DMCRet dmc_caller(DMCContext *context,
static DMCRet dmc_silent(DMCContext *context,
DMCHeap *heap,
- DMC_STACK_TYPE(Uint) *text,
+ DMC_STACK_TYPE(UWord) *text,
Eterm t,
int *constant)
{
@@ -3727,7 +3821,7 @@ static DMCRet dmc_silent(DMCContext *context,
static DMCRet dmc_fun(DMCContext *context,
DMCHeap *heap,
- DMC_STACK_TYPE(Uint) *text,
+ DMC_STACK_TYPE(UWord) *text,
Eterm t,
int *constant)
{
@@ -3844,7 +3938,7 @@ static DMCRet dmc_fun(DMCContext *context,
erl_exit(1,"ets:match() internal error, "
"guard with more than 3 arguments.");
}
- DMC_PUSH(*text, (Uint) b->biff);
+ DMC_PUSH(*text, (UWord) b->biff);
context->stack_used -= (((int) a) - 2);
if (context->stack_used > context->stack_need)
context->stack_need = context->stack_used;
@@ -3853,7 +3947,7 @@ static DMCRet dmc_fun(DMCContext *context,
static DMCRet dmc_expr(DMCContext *context,
DMCHeap *heap,
- DMC_STACK_TYPE(Uint) *text,
+ DMC_STACK_TYPE(UWord) *text,
Eterm t,
int *constant)
{
@@ -3916,7 +4010,7 @@ static DMCRet dmc_expr(DMCContext *context,
static DMCRet compile_guard_expr(DMCContext *context,
DMCHeap *heap,
- DMC_STACK_TYPE(Uint) *text,
+ DMC_STACK_TYPE(UWord) *text,
Eterm l)
{
DMCRet ret;
@@ -4230,7 +4324,7 @@ static Eterm match_spec_test(Process *p, Eterm against, Eterm spec, int trace)
Eterm l;
Uint32 ret_flags;
Uint sz;
- Eterm *save_cp;
+ BeamInstr *save_cp;
if (trace && !(is_list(against) || against == NIL)) {
return THE_NON_VALUE;
@@ -4271,17 +4365,18 @@ static Eterm match_spec_test(Process *p, Eterm against, Eterm spec, int trace)
++n;
l = CDR(list_val(l));
}
+ save_cp = p->cp;
+ p->cp = NULL;
+ res = erts_match_set_run(p, mps, arr, n, &ret_flags);
+ p->cp = save_cp;
} else {
n = 0;
- arr = (Eterm *) against;
+ arr = NULL;
+ res = erts_match_set_run_ets(p, mps, against, n, &ret_flags);
}
/* We are in the context of a BIF,
{caller} should return 'undefined' */
- save_cp = p->cp;
- p->cp = NULL;
- res = erts_match_set_run(p, mps, arr, n, &ret_flags);
- p->cp = save_cp;
if (is_non_value(res)) {
res = am_false;
}
@@ -4324,7 +4419,7 @@ static Eterm seq_trace_fake(Process *p, Eterm arg1)
static void db_match_dis(Binary *bp)
{
MatchProg *prog = Binary2MatchProg(bp);
- Uint *t = prog->text;
+ UWord *t = prog->text;
Uint n;
Eterm p;
int first;
@@ -4390,41 +4485,48 @@ static void db_match_dis(Binary *bp)
break;
case matchEqRef:
++t;
- n = thing_arityval(*t);
- ++t;
- erts_printf("EqRef\t(%d) {", (int) n);
- first = 1;
- while (n--) {
- if (first)
- first = 0;
- else
- erts_printf(", ");
-#ifdef ARCH_64
- erts_printf("0x%016bpx", *t);
+ {
+ RefThing *rt = (RefThing *) t;
+ int ri;
+ n = thing_arityval(rt->header);
+ erts_printf("EqRef\t(%d) {", (int) n);
+ first = 1;
+ for (ri = 0; ri < n; ++ri) {
+ if (first)
+ first = 0;
+ else
+ erts_printf(", ");
+#if defined(ARCH_64) && !HALFWORD_HEAP
+ erts_printf("0x%016bpx", rt->data.ui[ri]);
#else
- erts_printf("0x%08bpx", *t);
+ erts_printf("0x%08bpx", rt->data.ui[ri]);
#endif
- ++t;
+ }
}
+ t += TermWords(REF_THING_SIZE);
erts_printf("}\n");
break;
case matchEqBig:
++t;
n = thing_arityval(*t);
- ++t;
- erts_printf("EqBig\t(%d) {", (int) n);
- first = 1;
- while (n--) {
- if (first)
- first = 0;
- else
- erts_printf(", ");
-#ifdef ARCH_64
- erts_printf("0x%016bpx", *t);
+ {
+ Eterm *et = (Eterm *) t;
+ t += TermWords(n+1);
+ erts_printf("EqBig\t(%d) {", (int) n);
+ first = 1;
+ ++n;
+ while (n--) {
+ if (first)
+ first = 0;
+ else
+ erts_printf(", ");
+#if defined(ARCH_64) && !HALFWORD_HEAP
+ erts_printf("0x%016bpx", *et);
#else
- erts_printf("0x%08bpx", *t);
+ erts_printf("0x%08bpx", *et);
#endif
- ++t;
+ ++et;
+ }
}
erts_printf("}\n");
break;
@@ -4432,8 +4534,8 @@ static void db_match_dis(Binary *bp)
++t;
{
double num;
- memcpy(&num,t, 2 * sizeof(*t));
- t += 2;
+ memcpy(&num,t,sizeof(double));
+ t += TermWords(2);
erts_printf("EqFloat\t%f\n", num);
}
break;
diff --git a/erts/emulator/beam/erl_db_util.h b/erts/emulator/beam/erl_db_util.h
index 4fc7b4f52e..382e5dceb5 100644
--- a/erts/emulator/beam/erl_db_util.h
+++ b/erts/emulator/beam/erl_db_util.h
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1998-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1998-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -212,7 +212,7 @@ typedef struct db_table_common {
#endif
Eterm owner; /* Pid of the creator */
Eterm heir; /* Pid of the heir */
- Eterm heir_data; /* To send in ETS-TRANSFER (is_immed or (DbTerm*) */
+ UWord heir_data; /* To send in ETS-TRANSFER (is_immed or (DbTerm*) */
SysTimeval heir_started; /* To further identify the heir */
Eterm the_name; /* an atom */
Eterm id; /* atom | integer */
@@ -304,9 +304,9 @@ typedef struct match_prog {
Uint eheap_offset;
Uint stack_offset;
#ifdef DMC_DEBUG
- Uint* prog_end; /* End of program */
+ UWord* prog_end; /* End of program */
#endif
- Uint text[1]; /* Beginning of program */
+ UWord text[1]; /* Beginning of program */
} MatchProg;
/*
@@ -366,7 +366,7 @@ Binary *db_match_compile(Eterm *matchexpr, Eterm *guards,
Uint flags,
DMCErrInfo *err_info);
/* Returns newly allocated MatchProg binary with refc == 0*/
-Eterm db_prog_match(Process *p, Binary *prog, Eterm term, int arity,
+Eterm db_prog_match(Process *p, Binary *prog, Eterm term, Eterm *termp, int arity,
Uint32 *return_flags /* Zeroed on enter */);
/* returns DB_ERROR_NONE if matches, 1 if not matches and some db error on
error. */
diff --git a/erts/emulator/beam/erl_debug.c b/erts/emulator/beam/erl_debug.c
index e5c3c76fdd..9c7a47da0a 100644
--- a/erts/emulator/beam/erl_debug.c
+++ b/erts/emulator/beam/erl_debug.c
@@ -235,9 +235,9 @@ pps(Process* p, Eterm* stop)
}
while(sp >= stop) {
- erts_print(to, to_arg, "%0*lx: ", PTR_SIZE, (Eterm) sp);
+ erts_print(to, to_arg, "%0*lx: ", PTR_SIZE, (UWord) sp);
if (is_catch(*sp)) {
- erts_print(to, to_arg, "catch %d", (Uint)catch_pc(*sp));
+ erts_print(to, to_arg, "catch %ld", (UWord)catch_pc(*sp));
} else {
paranoid_display(to, to_arg, p, *sp);
}
@@ -895,5 +895,29 @@ void print_memory_info(Process *p)
#endif
erts_printf("+-----------------%s-%s-%s-%s-+\n",dashes,dashes,dashes,dashes);
}
+#if !HEAP_ON_C_STACK && defined(DEBUG)
+Eterm *erts_debug_allocate_tmp_heap(int size, Process *p)
+{
+ ErtsSchedulerData *sd = ((p == NULL) ? erts_get_scheduler_data() : ERTS_PROC_GET_SCHDATA(p));
+ int offset = sd->num_tmp_heap_used;
+
+ ASSERT(offset+size <= TMP_HEAP_SIZE);
+ return (sd->tmp_heap)+offset;
+}
+void erts_debug_use_tmp_heap(int size, Process *p)
+{
+ ErtsSchedulerData *sd = ((p == NULL) ? erts_get_scheduler_data() : ERTS_PROC_GET_SCHDATA(p));
+
+ sd->num_tmp_heap_used += size;
+ ASSERT(sd->num_tmp_heap_used <= TMP_HEAP_SIZE);
+}
+void erts_debug_unuse_tmp_heap(int size, Process *p)
+{
+ ErtsSchedulerData *sd = ((p == NULL) ? erts_get_scheduler_data() : ERTS_PROC_GET_SCHDATA(p));
+
+ sd->num_tmp_heap_used -= size;
+ ASSERT(sd->num_tmp_heap_used >= 0);
+}
+#endif
#endif
diff --git a/erts/emulator/beam/erl_debug.h b/erts/emulator/beam/erl_debug.h
index 74f4a00b63..bdfbaddbbf 100644
--- a/erts/emulator/beam/erl_debug.h
+++ b/erts/emulator/beam/erl_debug.h
@@ -1,26 +1,27 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2004-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2004-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
#ifndef _ERL_DEBUG_H_
#define _ERL_DEBUG_H_
-
#ifdef DEBUG
+#include "erl_term.h"
+
#ifdef HIPE
#include "hipe_debug.h"
#endif
@@ -92,6 +93,11 @@ extern void print_tagged_memory(Eterm *start, Eterm *end);
extern void print_untagged_memory(Eterm *start, Eterm *end);
extern void print_memory(Process *p);
extern void print_memory_info(Process *p);
+#if defined(DEBUG) && !HEAP_ON_C_STACK
+extern Eterm *erts_debug_allocate_tmp_heap(int, Process *);
+extern void erts_debug_use_tmp_heap(int, Process *);
+extern void erts_debug_unuse_tmp_heap(int, Process *);
+#endif
#ifdef HYBRID
extern void print_ma_info(void);
diff --git a/erts/emulator/beam/erl_driver.h b/erts/emulator/beam/erl_driver.h
index 489e74d960..15a4f44a7d 100644
--- a/erts/emulator/beam/erl_driver.h
+++ b/erts/emulator/beam/erl_driver.h
@@ -48,6 +48,10 @@
# define SIZEOF_LONG_LONG_SAVED__ SIZEOF_LONG_LONG
# undef SIZEOF_LONG_LONG
#endif
+#ifdef HALFWORD_HEAP_EMULATOR
+# define HALFWORD_HEAP_EMULATOR_SAVED__ HALFWORD_HEAP_EMULATOR
+# undef HALFWORD_HEAP_EMULATOR
+#endif
#include "erl_int_sizes_config.h"
#if defined(SIZEOF_CHAR_SAVED__) && SIZEOF_CHAR_SAVED__ != SIZEOF_CHAR
# error SIZEOF_CHAR mismatch
@@ -65,6 +69,11 @@
# error SIZEOF_LONG_LONG mismatch
#endif
+/* This is OK to override by the NIF/driver implementor */
+#if defined(HALFWORD_HEAP_EMULATOR_SAVED__) && !defined(HALFWORD_HEAP_EMULATOR)
+#define HALFWORD_HEAP_EMULATOR HALFWORD_HEAP_EMULATOR_SAVED__
+#endif
+
#include "erl_drv_nif.h"
#include <stdlib.h>
@@ -567,7 +576,7 @@ EXTERN int driver_send_term(ErlDrvPort ix, ErlDrvTermData to,
/* Async IO functions */
EXTERN long driver_async(ErlDrvPort ix,
- unsigned int* key,
+ unsigned long* key,
void (*async_invoke)(void*),
void* async_data,
void (*async_free)(void*));
diff --git a/erts/emulator/beam/erl_fun.c b/erts/emulator/beam/erl_fun.c
index 79e844b315..15d9538301 100644
--- a/erts/emulator/beam/erl_fun.c
+++ b/erts/emulator/beam/erl_fun.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2000-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2000-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -50,8 +50,8 @@ static void fun_free(ErlFunEntry* obj);
* to unloaded_fun[]. The -1 in unloaded_fun[0] will be interpreted
* as an illegal arity when attempting to call a fun.
*/
-static Eterm unloaded_fun_code[3] = {NIL, -1, 0};
-static Eterm* unloaded_fun = unloaded_fun_code + 2;
+static BeamInstr unloaded_fun_code[3] = {NIL, -1, 0};
+static BeamInstr* unloaded_fun = unloaded_fun_code + 2;
void
erts_init_fun_table(void)
@@ -207,7 +207,7 @@ erts_cleanup_funs(ErlFunThing* funp)
#endif
void
-erts_cleanup_funs_on_purge(Eterm* start, Eterm* end)
+erts_cleanup_funs_on_purge(BeamInstr* start, BeamInstr* end)
{
int limit;
HashBucket** bucket;
@@ -222,7 +222,7 @@ erts_cleanup_funs_on_purge(Eterm* start, Eterm* end)
while (b) {
ErlFunEntry* fe = (ErlFunEntry *) b;
- Eterm* addr = fe->address;
+ BeamInstr* addr = fe->address;
if (start <= addr && addr < end) {
fe->address = unloaded_fun;
diff --git a/erts/emulator/beam/erl_fun.h b/erts/emulator/beam/erl_fun.h
index fb5e75649b..944d4b3df5 100644
--- a/erts/emulator/beam/erl_fun.h
+++ b/erts/emulator/beam/erl_fun.h
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2000-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2000-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -33,10 +33,10 @@ typedef struct erl_fun_entry {
int index; /* New style index. */
int old_uniq; /* Unique number (old_style) */
int old_index; /* Old style index */
- Eterm* address; /* Pointer to code for fun */
+ BeamInstr* address; /* Pointer to code for fun */
#ifdef HIPE
- Eterm* native_address; /* Native entry code for fun. */
+ UWord* native_address; /* Native entry code for fun. */
#endif
Uint arity; /* The arity of the fun. */
@@ -58,7 +58,7 @@ typedef struct erl_fun_thing {
#endif
ErlFunEntry* fe; /* Pointer to fun entry. */
#ifdef HIPE
- Eterm* native_address; /* Native code for the fun. */
+ UWord* native_address; /* Native code for the fun. */
#endif
Uint arity; /* The arity of the fun. */
Uint num_free; /* Number of free variables (in env). */
@@ -86,7 +86,7 @@ void erts_erase_fun_entry(ErlFunEntry* fe);
#ifndef HYBRID /* FIND ME! */
void erts_cleanup_funs(ErlFunThing* funp);
#endif
-void erts_cleanup_funs_on_purge(Eterm* start, Eterm* end);
+void erts_cleanup_funs_on_purge(BeamInstr* start, BeamInstr* end);
void erts_dump_fun_entries(int, void *);
#endif
diff --git a/erts/emulator/beam/erl_gc.c b/erts/emulator/beam/erl_gc.c
index e9bf37a173..9ed566e66e 100644
--- a/erts/emulator/beam/erl_gc.c
+++ b/erts/emulator/beam/erl_gc.c
@@ -126,7 +126,7 @@ static void disallow_heap_frag_ref_in_old_heap(Process* p);
static void disallow_heap_frag_ref(Process* p, Eterm* n_htop, Eterm* objv, int nobj);
#endif
-#ifdef ARCH_64
+#if defined(ARCH_64) && !HALFWORD_HEAP
# define MAX_HEAP_SIZES 154
#else
# define MAX_HEAP_SIZES 55
@@ -1551,7 +1551,7 @@ disallow_heap_frag_ref_in_old_heap(Process* p)
val = *hp++;
switch (primary_tag(val)) {
case TAG_PRIMARY_BOXED:
- ptr = (Eterm *) val;
+ ptr = (Eterm *) EXPAND_POINTER(val);
if (!in_area(ptr, old_heap, old_heap_size)) {
if (in_area(ptr, new_heap, new_heap_size)) {
abort();
@@ -1564,7 +1564,7 @@ disallow_heap_frag_ref_in_old_heap(Process* p)
}
break;
case TAG_PRIMARY_LIST:
- ptr = (Eterm *) val;
+ ptr = (Eterm *) EXPAND_POINTER(val);
if (!in_area(ptr, old_heap, old_heap_size)) {
if (in_area(ptr, new_heap, new_heap_size)) {
abort();
diff --git a/erts/emulator/beam/erl_goodfit_alloc.c b/erts/emulator/beam/erl_goodfit_alloc.c
index ea2ba4d55c..76b206d76f 100644
--- a/erts/emulator/beam/erl_goodfit_alloc.c
+++ b/erts/emulator/beam/erl_goodfit_alloc.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2003-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2003-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -49,30 +49,30 @@
#define MIN_MBC_FIRST_FREE_SZ (4*1024)
#define MAX_SUB_MASK_IX \
- ((((Uint)1) << (NO_OF_BKT_IX_BITS - SUB_MASK_IX_SHIFT)) - 1)
-#define MAX_SUB_BKT_IX ((((Uint)1) << SUB_MASK_IX_SHIFT) - 1)
+ ((((UWord)1) << (NO_OF_BKT_IX_BITS - SUB_MASK_IX_SHIFT)) - 1)
+#define MAX_SUB_BKT_IX ((((UWord)1) << SUB_MASK_IX_SHIFT) - 1)
#define MAX_BKT_IX (NO_OF_BKTS - 1)
-#define MIN_BLK_SZ UNIT_CEILING(sizeof(GFFreeBlock_t) + sizeof(Uint))
+#define MIN_BLK_SZ UNIT_CEILING(sizeof(GFFreeBlock_t) + sizeof(UWord))
-#define IX2SBIX(IX) ((IX) & (~(~((Uint)0) << SUB_MASK_IX_SHIFT)))
+#define IX2SBIX(IX) ((IX) & (~(~((UWord)0) << SUB_MASK_IX_SHIFT)))
#define IX2SMIX(IX) ((IX) >> SUB_MASK_IX_SHIFT)
#define MAKE_BKT_IX(SMIX, SBIX) \
- ((((Uint)(SMIX)) << SUB_MASK_IX_SHIFT) | ((Uint)(SBIX)))
+ ((((UWord)(SMIX)) << SUB_MASK_IX_SHIFT) | ((UWord)(SBIX)))
#define SET_BKT_MASK_IX(BM, IX) \
do { \
int sub_mask_ix__ = IX2SMIX((IX)); \
- (BM).main |= (((Uint) 1) << sub_mask_ix__); \
- (BM).sub[sub_mask_ix__] |= (((Uint)1) << IX2SBIX((IX))); \
+ (BM).main |= (((UWord) 1) << sub_mask_ix__); \
+ (BM).sub[sub_mask_ix__] |= (((UWord)1) << IX2SBIX((IX))); \
} while (0)
#define UNSET_BKT_MASK_IX(BM, IX) \
do { \
int sub_mask_ix__ = IX2SMIX((IX)); \
- (BM).sub[sub_mask_ix__] &= ~(((Uint)1) << IX2SBIX((IX))); \
+ (BM).sub[sub_mask_ix__] &= ~(((UWord)1) << IX2SBIX((IX))); \
if (!(BM).sub[sub_mask_ix__]) \
- (BM).main &= ~(((Uint)1) << sub_mask_ix__); \
+ (BM).main &= ~(((UWord)1) << sub_mask_ix__); \
} while (0)
/* Buckets ... */
@@ -263,8 +263,8 @@ find_bucket(BucketMask_t *bmask, int min_index)
while(max != min) { \
mid = ((max - min) >> 1) + min; \
if((BitMask) \
- & (~(~((Uint) 0) << (mid + 1))) \
- & (~((Uint) 0) << min)) \
+ & (~(~((UWord) 0) << (mid + 1))) \
+ & (~((UWord) 0) << min)) \
max = mid; \
else \
min = mid + 1; \
@@ -272,21 +272,21 @@ find_bucket(BucketMask_t *bmask, int min_index)
(MinBit) = min
- ASSERT(bmask->main < (((Uint) 1) << (MAX_SUB_MASK_IX+1)));
+ ASSERT(bmask->main < (((UWord) 1) << (MAX_SUB_MASK_IX+1)));
sub_mask_ix = IX2SMIX(min_index);
- if ((bmask->main & (~((Uint) 0) << sub_mask_ix)) == 0)
+ if ((bmask->main & (~((UWord) 0) << sub_mask_ix)) == 0)
return -1;
/* There exists a non empty bucket; find it... */
- if (bmask->main & (((Uint) 1) << sub_mask_ix)) {
+ if (bmask->main & (((UWord) 1) << sub_mask_ix)) {
sub_bkt_ix = IX2SBIX(min_index);
- if ((bmask->sub[sub_mask_ix] & (~((Uint) 0) << sub_bkt_ix)) == 0) {
+ if ((bmask->sub[sub_mask_ix] & (~((UWord) 0) << sub_bkt_ix)) == 0) {
sub_mask_ix++;
sub_bkt_ix = 0;
- if ((bmask->main & (~((Uint) 0)<< sub_mask_ix)) == 0)
+ if ((bmask->main & (~((UWord) 0)<< sub_mask_ix)) == 0)
return -1;
}
else
@@ -299,17 +299,17 @@ find_bucket(BucketMask_t *bmask, int min_index)
ASSERT(sub_mask_ix <= MAX_SUB_MASK_IX);
/* Has to be a bit > sub_mask_ix */
- ASSERT(bmask->main & (~((Uint) 0) << (sub_mask_ix)));
+ ASSERT(bmask->main & (~((UWord) 0) << (sub_mask_ix)));
GET_MIN_BIT(sub_mask_ix, bmask->main, sub_mask_ix, MAX_SUB_MASK_IX);
find_sub_bkt_ix:
ASSERT(sub_mask_ix <= MAX_SUB_MASK_IX);
ASSERT(sub_bkt_ix <= MAX_SUB_BKT_IX);
- if ((bmask->sub[sub_mask_ix] & (((Uint) 1) << sub_bkt_ix)) == 0) {
+ if ((bmask->sub[sub_mask_ix] & (((UWord) 1) << sub_bkt_ix)) == 0) {
ASSERT(sub_mask_ix + 1 <= MAX_SUB_BKT_IX);
/* Has to be a bit > sub_bkt_ix */
- ASSERT(bmask->sub[sub_mask_ix] & (~((Uint) 0) << sub_bkt_ix));
+ ASSERT(bmask->sub[sub_mask_ix] & (~((UWord) 0) << sub_bkt_ix));
GET_MIN_BIT(sub_bkt_ix,
bmask->sub[sub_mask_ix],
@@ -336,7 +336,7 @@ search_bucket(Allctr_t *allctr, int ix, Uint size)
Uint min_sz;
Uint blk_sz;
Uint cand_sz = 0;
- Uint max_blk_search;
+ UWord max_blk_search;
GFFreeBlock_t *blk;
GFFreeBlock_t *cand = NULL;
int blk_on_lambc;
@@ -615,9 +615,9 @@ check_block(Allctr_t *allctr, Block_t * blk, int free_block)
Uint blk_sz = BLK_SZ(blk);
bi = BKT_IX(gfallctr, blk_sz);
- ASSERT(gfallctr->bucket_mask.main & (((Uint) 1) << IX2SMIX(bi)));
+ ASSERT(gfallctr->bucket_mask.main & (((UWord) 1) << IX2SMIX(bi)));
ASSERT(gfallctr->bucket_mask.sub[IX2SMIX(bi)]
- & (((Uint) 1) << IX2SBIX(bi)));
+ & (((UWord) 1) << IX2SBIX(bi)));
found = 0;
for (fblk = gfallctr->buckets[bi]; fblk; fblk = fblk->next)
@@ -648,9 +648,9 @@ check_mbc(Allctr_t *allctr, Carrier_t *mbc)
int bi;
for(bi = 0; bi < NO_OF_BKTS; bi++) {
- if ((gfallctr->bucket_mask.main & (((Uint) 1) << IX2SMIX(bi)))
+ if ((gfallctr->bucket_mask.main & (((UWord) 1) << IX2SMIX(bi)))
&& (gfallctr->bucket_mask.sub[IX2SMIX(bi)]
- & (((Uint) 1) << IX2SBIX(bi)))) {
+ & (((UWord) 1) << IX2SBIX(bi)))) {
ASSERT(gfallctr->buckets[bi] != NULL);
}
else {
diff --git a/erts/emulator/beam/erl_goodfit_alloc.h b/erts/emulator/beam/erl_goodfit_alloc.h
index 3d1b8c01f6..a554a6f466 100644
--- a/erts/emulator/beam/erl_goodfit_alloc.h
+++ b/erts/emulator/beam/erl_goodfit_alloc.h
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2003-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2003-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -28,7 +28,7 @@
typedef struct GFAllctr_t_ GFAllctr_t;
typedef struct {
- Uint mbsd;
+ UWord mbsd;
} GFAllctrInit_t;
#define ERTS_DEFAULT_GF_ALLCTR_INIT { \
@@ -49,18 +49,18 @@ Allctr_t *erts_gfalc_start(GFAllctr_t *, GFAllctrInit_t *, AllctrInit_t *);
#include "erl_alloc_util.h"
#define NO_OF_BKT_IX_BITS (8)
-#ifdef ARCH_64
+#if defined(ARCH_64)
# define SUB_MASK_IX_SHIFT (6)
#else
# define SUB_MASK_IX_SHIFT (5)
#endif
-#define NO_OF_BKTS (((Uint) 1) << NO_OF_BKT_IX_BITS)
-#define NO_OF_SUB_MASKS (NO_OF_BKTS/(((Uint) 1) << SUB_MASK_IX_SHIFT))
+#define NO_OF_BKTS (((UWord) 1) << NO_OF_BKT_IX_BITS)
+#define NO_OF_SUB_MASKS (NO_OF_BKTS/(((UWord) 1) << SUB_MASK_IX_SHIFT))
typedef struct {
- Uint main;
- Uint sub[NO_OF_SUB_MASKS];
-} BucketMask_t;
+ UWord main;
+ UWord sub[NO_OF_SUB_MASKS];
+} BucketMask_t;
typedef struct GFFreeBlock_t_ GFFreeBlock_t;
struct GFFreeBlock_t_ {
@@ -74,11 +74,11 @@ struct GFAllctr_t_ {
char * last_aux_mbc_start;
char * last_aux_mbc_end;
- Uint bkt_max_size_d;
- Uint bkt_intrvl_d;
+ UWord bkt_max_size_d;
+ UWord bkt_intrvl_d;
BucketMask_t bucket_mask;
GFFreeBlock_t * buckets[NO_OF_BKTS];
- Uint max_blk_search;
+ UWord max_blk_search;
};
diff --git a/erts/emulator/beam/erl_instrument.c b/erts/emulator/beam/erl_instrument.c
index 3f022f92b8..f3f3c22933 100644
--- a/erts/emulator/beam/erl_instrument.c
+++ b/erts/emulator/beam/erl_instrument.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2003-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2003-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -540,18 +540,18 @@ static void dump_memory_map_to_stream(FILE *fp)
if (is_internal_pid(bp->pid))
fprintf(fp,
"{%lu, %lu, %lu, {%lu,%lu,%lu}}.\n",
- (Uint) bp->type_no,
- (Uint) bp->mem,
- (Uint) bp->size,
- (Uint) pid_channel_no(bp->pid),
- (Uint) pid_number(bp->pid),
- (Uint) pid_serial(bp->pid));
+ (UWord) bp->type_no,
+ (UWord) bp->mem,
+ (UWord) bp->size,
+ (UWord) pid_channel_no(bp->pid),
+ (UWord) pid_number(bp->pid),
+ (UWord) pid_serial(bp->pid));
else
fprintf(fp,
"{%lu, %lu, %lu, undefined}.\n",
- (Uint) bp->type_no,
- (Uint) bp->mem,
- (Uint) bp->size);
+ (UWord) bp->type_no,
+ (UWord) bp->mem,
+ (UWord) bp->size);
}
if (lock)
@@ -638,7 +638,7 @@ Eterm erts_instr_get_memory_map(Process *proc)
hsz += 4;
}
- if ((Uint) bp->mem > MAX_SMALL)
+ if ((UWord) bp->mem > MAX_SMALL)
hsz += BIG_UINT_HEAP_SIZE;
if (bp->size > MAX_SMALL)
hsz += BIG_UINT_HEAP_SIZE;
@@ -749,12 +749,12 @@ Eterm erts_instr_get_memory_map(Process *proc)
#endif
type = make_small(bp->type_no);
- if ((Uint) bp->mem > MAX_SMALL) {
- ptr = uint_to_big((Uint) bp->mem, hp);
+ if ((UWord) bp->mem > MAX_SMALL) {
+ ptr = uint_to_big((UWord) bp->mem, hp);
hp += BIG_UINT_HEAP_SIZE;
}
else
- ptr = make_small((Uint) bp->mem);
+ ptr = make_small((UWord) bp->mem);
if (bp->size > MAX_SMALL) {
size = uint_to_big(bp->size, hp);
@@ -962,12 +962,12 @@ dump_stat_to_stream(FILE *fp, int begin_max_period)
fprintf(fp,
"{total,[{total,[{sizes,%lu,%lu,%lu},{blocks,%lu,%lu,%lu}]}]}.\n",
- stats->tot.size,
- stats->tot.max_size,
- stats->tot.max_size_ever,
- stats->tot.blocks,
- stats->tot.max_blocks,
- stats->tot.max_blocks_ever);
+ (UWord) stats->tot.size,
+ (UWord) stats->tot.max_size,
+ (UWord) stats->tot.max_size_ever,
+ (UWord) stats->tot.blocks,
+ (UWord) stats->tot.max_blocks,
+ (UWord) stats->tot.max_blocks_ever);
a_max = 0;
a_min = ~0;
@@ -992,12 +992,12 @@ dump_stat_to_stream(FILE *fp, int begin_max_period)
"%s{%s,[{sizes,%lu,%lu,%lu},{blocks,%lu,%lu,%lu}]}%s",
i == a_min ? "{allocators,\n [" : " ",
ERTS_ALC_A2AD(i),
- stats->a[i].size,
- stats->a[i].max_size,
- stats->a[i].max_size_ever,
- stats->a[i].blocks,
- stats->a[i].max_blocks,
- stats->a[i].max_blocks_ever,
+ (UWord) stats->a[i].size,
+ (UWord) stats->a[i].max_size,
+ (UWord) stats->a[i].max_size_ever,
+ (UWord) stats->a[i].blocks,
+ (UWord) stats->a[i].max_blocks,
+ (UWord) stats->a[i].max_blocks_ever,
i == a_max ? "]}.\n" : ",\n");
}
}
@@ -1009,12 +1009,12 @@ dump_stat_to_stream(FILE *fp, int begin_max_period)
"%s{%s,[{sizes,%lu,%lu,%lu},{blocks,%lu,%lu,%lu}]}%s",
i == ERTS_ALC_C_MIN ? "{classes,\n [" : " ",
ERTS_ALC_C2CD(i),
- stats->c[i].size,
- stats->c[i].max_size,
- stats->c[i].max_size_ever,
- stats->c[i].blocks,
- stats->c[i].max_blocks,
- stats->c[i].max_blocks_ever,
+ (UWord) stats->c[i].size,
+ (UWord) stats->c[i].max_size,
+ (UWord) stats->c[i].max_size_ever,
+ (UWord) stats->c[i].blocks,
+ (UWord) stats->c[i].max_blocks,
+ (UWord) stats->c[i].max_blocks_ever,
i == ERTS_ALC_C_MAX ? "]}.\n" : ",\n" );
}
@@ -1025,12 +1025,12 @@ dump_stat_to_stream(FILE *fp, int begin_max_period)
"%s{%s,[{sizes,%lu,%lu,%lu},{blocks,%lu,%lu,%lu}]}%s",
i == ERTS_ALC_N_MIN ? "{types,\n [" : " ",
ERTS_ALC_N2TD(i),
- stats->n[i].size,
- stats->n[i].max_size,
- stats->n[i].max_size_ever,
- stats->n[i].blocks,
- stats->n[i].max_blocks,
- stats->n[i].max_blocks_ever,
+ (UWord) stats->n[i].size,
+ (UWord) stats->n[i].max_size,
+ (UWord) stats->n[i].max_size_ever,
+ (UWord) stats->n[i].blocks,
+ (UWord) stats->n[i].max_blocks,
+ (UWord) stats->n[i].max_blocks_ever,
i == ERTS_ALC_N_MAX ? "]}.\n" : ",\n" );
}
diff --git a/erts/emulator/beam/erl_lock_check.c b/erts/emulator/beam/erl_lock_check.c
index 074b08ea57..6ff5c1b9da 100644
--- a/erts/emulator/beam/erl_lock_check.c
+++ b/erts/emulator/beam/erl_lock_check.c
@@ -155,6 +155,9 @@ static erts_lc_lock_order_t erts_lock_order[] = {
{ "fix_alloc", "index" },
{ "alcu_allocator", "index" },
{ "mseg", NULL },
+#ifdef HALFWORD_HEAP
+ { "pmmap", NULL },
+#endif
#ifdef ERTS_SMP
{ "port_task_pre_alloc_lock", "address" },
{ "port_taskq_pre_alloc_lock", "address" },
@@ -1231,6 +1234,8 @@ void
erts_lc_init_lock(erts_lc_lock_t *lck, char *name, Uint16 flags)
{
lck->id = erts_lc_get_lock_order_id(name);
+
+ /* XXX:PaN What to do with the extra information? */
lck->extra = make_boxed(&lck->extra);
lck->flags = flags;
lck->inited = ERTS_LC_INITITALIZED;
diff --git a/erts/emulator/beam/erl_message.h b/erts/emulator/beam/erl_message.h
index 5cf7c209bd..459c6363aa 100644
--- a/erts/emulator/beam/erl_message.h
+++ b/erts/emulator/beam/erl_message.h
@@ -49,7 +49,7 @@ typedef struct erl_heap_fragment ErlHeapFragment;
struct erl_heap_fragment {
ErlHeapFragment* next; /* Next heap fragment */
ErlOffHeap off_heap; /* Offset heap data. */
- unsigned size; /* Size in words of mem */
+ unsigned size; /* Size in (half)words of mem */
unsigned used_size; /* With terms to be moved to heap by GC */
Eterm mem[1]; /* Data */
};
diff --git a/erts/emulator/beam/erl_mtrace.c b/erts/emulator/beam/erl_mtrace.c
index 8b8ac2ec80..9cf55ee319 100644
--- a/erts/emulator/beam/erl_mtrace.c
+++ b/erts/emulator/beam/erl_mtrace.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2003-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2003-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -79,7 +79,7 @@ static erts_mtx_t mtrace_buf_mutex;
#define UI16_SZ (2)
#define UI32_SZ (4)
#define UI64_SZ (8)
-#ifdef ARCH_64
+#ifdef ARCH_64 /* XXX:PaN Halfword? (whole file...) */
# define UI_SZ UI64_SZ
#else
# define UI_SZ UI32_SZ
@@ -188,7 +188,7 @@ check_alloc_entry(byte *sp, byte *ep,
byte tag,
Uint16 ct_no, int ct_no_n,
Uint16 type, int type_n,
- Uint res, int res_n,
+ UWord res, int res_n,
Uint size, int size_n,
Uint32 ti,int ti_n);
void
@@ -196,8 +196,8 @@ check_realloc_entry(byte *sp, byte *ep,
byte tag,
Uint16 ct_no, int ct_no_n,
Uint16 type, int type_n,
- Uint res, int res_n,
- Uint ptr, int ptr_n,
+ UWord res, int res_n,
+ UWord ptr, int ptr_n,
Uint size, int size_n,
Uint32 ti,int ti_n);
void
@@ -205,7 +205,7 @@ check_free_entry(byte *sp, byte *ep,
byte tag,
Uint16 ct_no, int ct_no_n,
Uint16 t_no, int t_no_n,
- Uint ptr, int ptr_n,
+ UWord ptr, int ptr_n,
Uint32 ti,int ti_n);
void
check_time_inc_entry(byte *sp, byte *ep,
@@ -785,7 +785,7 @@ write_alloc_entry(byte tag,
tag,
ct_no, ct_no_n,
t_no, t_no_n,
- (Uint) res, res_n,
+ (UWord) res, res_n,
size, size_n,
ti, ti_n);
#endif
@@ -865,8 +865,8 @@ write_realloc_entry(byte tag,
tag,
ct_no, ct_no_n,
t_no, t_no_n,
- (Uint) res, res_n,
- (Uint) ptr, ptr_n,
+ (UWord) res, res_n,
+ (UWord) ptr, ptr_n,
size, size_n,
ti, ti_n);
#endif
@@ -934,7 +934,7 @@ write_free_entry(byte tag,
tag,
ct_no, ct_no_n,
t_no, t_no_n,
- (Uint) ptr, ptr_n,
+ (UWord) ptr, ptr_n,
ti, ti_n);
#endif
}
@@ -1135,7 +1135,7 @@ check_alloc_entry(byte *sp, byte *ep,
byte tag,
Uint16 ct_no, int ct_no_n,
Uint16 t_no, int t_no_n,
- Uint res, int res_n,
+ UWord res, int res_n,
Uint size, int size_n,
Uint32 ti,int ti_n)
{
@@ -1163,8 +1163,8 @@ check_realloc_entry(byte *sp, byte *ep,
byte tag,
Uint16 ct_no, int ct_no_n,
Uint16 t_no, int t_no_n,
- Uint res, int res_n,
- Uint ptr, int ptr_n,
+ UWord res, int res_n,
+ UWord ptr, int ptr_n,
Uint size, int size_n,
Uint32 ti,int ti_n)
{
@@ -1193,7 +1193,7 @@ check_free_entry(byte *sp, byte *ep,
byte tag,
Uint16 ct_no, int ct_no_n,
Uint16 t_no, int t_no_n,
- Uint ptr, int ptr_n,
+ UWord ptr, int ptr_n,
Uint32 ti,int ti_n)
{
byte *p = sp;
diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c
index 585a6c1fdf..41a9e17c86 100644
--- a/erts/emulator/beam/erl_nif.c
+++ b/erts/emulator/beam/erl_nif.c
@@ -496,9 +496,9 @@ int enif_get_atom(ErlNifEnv* env, Eterm atom, char* buf, unsigned len)
int enif_get_int(ErlNifEnv* env, Eterm term, int* ip)
{
-#if SIZEOF_INT == SIZEOF_VOID_P
+#if SIZEOF_INT == ERTS_SIZEOF_ETERM
return term_to_Sint(term, (Sint*)ip);
-#elif SIZEOF_LONG == SIZEOF_VOID_P
+#elif SIZEOF_LONG == ERTS_SIZEOF_ETERM
Sint i;
if (!term_to_Sint(term, &i) || i < INT_MIN || i > INT_MAX) {
return 0;
@@ -512,9 +512,9 @@ int enif_get_int(ErlNifEnv* env, Eterm term, int* ip)
int enif_get_uint(ErlNifEnv* env, Eterm term, unsigned* ip)
{
-#if SIZEOF_INT == SIZEOF_VOID_P
+#if SIZEOF_INT == ERTS_SIZEOF_ETERM
return term_to_Uint(term, (Uint*)ip);
-#elif SIZEOF_LONG == SIZEOF_VOID_P
+#elif SIZEOF_LONG == ERTS_SIZEOF_ETERM
Uint i;
if (!term_to_Uint(term, &i) || i > UINT_MAX) {
return 0;
@@ -526,8 +526,13 @@ int enif_get_uint(ErlNifEnv* env, Eterm term, unsigned* ip)
int enif_get_long(ErlNifEnv* env, Eterm term, long* ip)
{
-#if SIZEOF_LONG == SIZEOF_VOID_P
+#if SIZEOF_LONG == ERTS_SIZEOF_ETERM
return term_to_Sint(term, ip);
+#elif SIZEOF_INT == ERTS_SIZEOF_ETERM
+ Uint u;
+ term_to_Sint(term, u);
+ *ip = (long) u;
+ return 1;
#else
# error Unknown long word size
#endif
@@ -535,8 +540,14 @@ int enif_get_long(ErlNifEnv* env, Eterm term, long* ip)
int enif_get_ulong(ErlNifEnv* env, Eterm term, unsigned long* ip)
{
-#if SIZEOF_LONG == SIZEOF_VOID_P
+#if SIZEOF_LONG == ERTS_SIZEOF_ETERM
return term_to_Uint(term, ip);
+#elif SIZEOF_INT == ERTS_SIZEOF_ETERM
+ Uint u;
+ int r;
+ r = term_to_Uint(term, &u);
+ *ip = (unsigned long) u;
+ return r;
#else
# error Unknown long word size
#endif
@@ -565,27 +576,24 @@ int enif_get_list_cell(ErlNifEnv* env, Eterm term, Eterm* head, Eterm* tail)
ERL_NIF_TERM enif_make_int(ErlNifEnv* env, int i)
{
-#if SIZEOF_INT == SIZEOF_VOID_P
+#if SIZEOF_INT == ERTS_SIZEOF_ETERM
return IS_SSMALL(i) ? make_small(i) : small_to_big(i,alloc_heap(env,2));
-#elif SIZEOF_LONG == SIZEOF_VOID_P
+#elif SIZEOF_LONG == ERTS_SIZEOF_ETERM
return make_small(i);
#endif
}
ERL_NIF_TERM enif_make_uint(ErlNifEnv* env, unsigned i)
{
-#if SIZEOF_INT == SIZEOF_VOID_P
+#if SIZEOF_INT == ERTS_SIZEOF_ETERM
return IS_USMALL(0,i) ? make_small(i) : uint_to_big(i,alloc_heap(env,2));
-#elif SIZEOF_LONG == SIZEOF_VOID_P
+#elif SIZEOF_LONG == ERTS_SIZEOF_ETERM
return make_small(i);
#endif
}
ERL_NIF_TERM enif_make_long(ErlNifEnv* env, long i)
{
-#if SIZEOF_LONG != SIZEOF_VOID_P
-# error Unknown long word size
-#endif
return IS_SSMALL(i) ? make_small(i) : small_to_big(i, alloc_heap(env,2));
}
@@ -967,34 +975,34 @@ unsigned enif_sizeof_resource(ErlNifEnv* env, void* obj)
***************************************************************************/
-static Uint** get_func_pp(Eterm* mod_code, Eterm f_atom, unsigned arity)
+static BeamInstr** get_func_pp(BeamInstr* mod_code, Eterm f_atom, unsigned arity)
{
int n = (int) mod_code[MI_NUM_FUNCTIONS];
int j;
for (j = 0; j < n; ++j) {
- Uint* code_ptr = (Uint*) mod_code[MI_FUNCTIONS+j];
- ASSERT(code_ptr[0] == (Uint) BeamOp(op_i_func_info_IaaI));
+ BeamInstr* code_ptr = (BeamInstr*) mod_code[MI_FUNCTIONS+j];
+ ASSERT(code_ptr[0] == (BeamInstr) BeamOp(op_i_func_info_IaaI));
if (f_atom == ((Eterm) code_ptr[3])
&& arity == ((unsigned) code_ptr[4])) {
- return (Uint**) &mod_code[MI_FUNCTIONS+j];
+ return (BeamInstr**) &mod_code[MI_FUNCTIONS+j];
}
}
return NULL;
}
-/*static void refresh_cached_nif_data(Eterm* mod_code,
+/*static void refresh_cached_nif_data(BeamInstr* mod_code,
struct erl_module_nif* mod_nif)
{
int i;
for (i=0; i < mod_nif->entry->num_of_funcs; i++) {
Eterm f_atom;
ErlNifFunc* func = &mod_nif->entry->funcs[i];
- Uint* code_ptr;
+ BeamInstr* code_ptr;
erts_atom_get(func->name, sys_strlen(func->name), &f_atom);
code_ptr = *get_func_pp(mod_code, f_atom, func->arity);
- code_ptr[5+2] = (Uint) mod_nif->priv_data;
+ code_ptr[5+2] = ((BeamInstr) mod_nif->priv_data;
}
}*/
@@ -1098,7 +1106,7 @@ BIF_RETTYPE load_nif_2(BIF_ALIST_2)
Module* mod;
Eterm mod_atom;
Eterm f_atom;
- Eterm* caller;
+ BeamInstr* caller;
ErtsSysDdllError errdesc = ERTS_SYS_DDLL_ERROR_INIT;
Eterm ret = am_ok;
int veto;
@@ -1165,7 +1173,7 @@ BIF_RETTYPE load_nif_2(BIF_ALIST_2)
/*erts_fprintf(stderr, "Found module %T\r\n", mod_atom);*/
for (i=0; i < entry->num_of_funcs && ret==am_ok; i++) {
- Uint** code_pp;
+ BeamInstr** code_pp;
ErlNifFunc* f = &entry->funcs[i];
if (!erts_atom_get(f->name, sys_strlen(f->name), &f_atom)
|| (code_pp = get_func_pp(mod->code, f_atom, f->arity))==NULL) {
@@ -1268,22 +1276,22 @@ BIF_RETTYPE load_nif_2(BIF_ALIST_2)
mod->nif = lib;
for (i=0; i < entry->num_of_funcs; i++)
{
- Uint* code_ptr;
+ BeamInstr* code_ptr;
erts_atom_get(entry->funcs[i].name, sys_strlen(entry->funcs[i].name), &f_atom);
code_ptr = *get_func_pp(mod->code, f_atom, entry->funcs[i].arity);
if (code_ptr[1] == 0) {
- code_ptr[5+0] = (Uint) BeamOp(op_call_nif);
+ code_ptr[5+0] = (BeamInstr) BeamOp(op_call_nif);
}
else { /* Function traced, patch the original instruction word */
BpData* bp = (BpData*) code_ptr[1];
- bp->orig_instr = (Uint) BeamOp(op_call_nif);
+ bp->orig_instr = (BeamInstr) BeamOp(op_call_nif);
}
- code_ptr[5+1] = (Uint) entry->funcs[i].fptr;
- code_ptr[5+2] = (Uint) lib;
+ code_ptr[5+1] = (BeamInstr) entry->funcs[i].fptr;
+ code_ptr[5+2] = (BeamInstr) lib;
}
}
- else {
+ else {
error:
ASSERT(ret != am_ok);
if (lib != NULL) {
diff --git a/erts/emulator/beam/erl_nif.h b/erts/emulator/beam/erl_nif.h
index 1ccf00293e..d0f6424724 100644
--- a/erts/emulator/beam/erl_nif.h
+++ b/erts/emulator/beam/erl_nif.h
@@ -34,7 +34,37 @@
#include <stdlib.h>
+#ifdef SIZEOF_CHAR
+# define SIZEOF_CHAR_SAVED__ SIZEOF_CHAR
+# undef SIZEOF_CHAR
+#endif
+#ifdef SIZEOF_SHORT
+# define SIZEOF_SHORT_SAVED__ SIZEOF_SHORT
+# undef SIZEOF_SHORT
+#endif
+#ifdef SIZEOF_INT
+# define SIZEOF_INT_SAVED__ SIZEOF_INT
+# undef SIZEOF_INT
+#endif
+#ifdef SIZEOF_LONG
+# define SIZEOF_LONG_SAVED__ SIZEOF_LONG
+# undef SIZEOF_LONG
+#endif
+#ifdef SIZEOF_LONG_LONG
+# define SIZEOF_LONG_LONG_SAVED__ SIZEOF_LONG_LONG
+# undef SIZEOF_LONG_LONG
+#endif
+#ifdef HALFWORD_HEAP_EMULATOR
+# define HALFWORD_HEAP_EMULATOR_SAVED__ HALFWORD_HEAP_EMULATOR
+# undef HALFWORD_HEAP_EMULATOR
+#endif
+#include "erl_int_sizes_config.h"
+
+#ifdef HALFWORD_HEAP_EMULATOR
+typedef unsigned int ERL_NIF_TERM;
+#else
typedef unsigned long ERL_NIF_TERM;
+#endif
struct enif_environment_t;
typedef struct enif_environment_t ErlNifEnv;
diff --git a/erts/emulator/beam/erl_node_container_utils.h b/erts/emulator/beam/erl_node_container_utils.h
index 87dbfc2a04..ae1316eba2 100644
--- a/erts/emulator/beam/erl_node_container_utils.h
+++ b/erts/emulator/beam/erl_node_container_utils.h
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2001-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2001-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -251,7 +251,7 @@ extern int erts_use_r9_pids_ports;
* Refs *
\* */
-#ifdef ARCH_64
+#if defined(ARCH_64) && !HALFWORD_HEAP
#define internal_ref_no_of_numbers(x) \
(internal_ref_data((x))[0])
diff --git a/erts/emulator/beam/erl_node_tables.c b/erts/emulator/beam/erl_node_tables.c
index 42b28d987c..5865d33138 100644
--- a/erts/emulator/beam/erl_node_tables.c
+++ b/erts/emulator/beam/erl_node_tables.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2001-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2001-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -1109,10 +1109,23 @@ insert_offheap(ErlOffHeap *oh, int type, Eterm id)
break;
}
if (insert_bin) {
- Uint id_heap[BIG_UINT_HEAP_SIZE];
+#if HALFWORD_HEAP
+ UWord val = (UWord) pb->val;
+ DeclareTmpHeapNoproc(id_heap,BIG_UINT_HEAP_SIZE*2); /* extra place allocated */
+#else
+ DeclareTmpHeapNoproc(id_heap,BIG_UINT_HEAP_SIZE);
+#endif
Uint *hp = &id_heap[0];
InsertedBin *nib;
+#if HALFWORD_HEAP
+ int actual_need = BIG_UWORD_HEAP_SIZE(val);
+ ASSERT(actual_need <= (BIG_UINT_HEAP_SIZE*2));
+ UseTmpHeapNoproc(actual_need);
+ a.id = erts_bld_uword(&hp, NULL, (UWord) val);
+#else
+ UseTmpHeapNoproc(BIG_UINT_HEAP_SIZE);
a.id = erts_bld_uint(&hp, NULL, (Uint) pb->val);
+#endif
erts_match_prog_foreach_offheap(pb->val,
insert_offheap2,
(void *) &a);
@@ -1120,6 +1133,11 @@ insert_offheap(ErlOffHeap *oh, int type, Eterm id)
nib->bin_val = pb->val;
nib->next = inserted_bins;
inserted_bins = nib;
+#if HALFWORD_HEAP
+ UnUseTmpHeapNoproc(actual_need);
+#else
+ UnUseTmpHeapNoproc(BIG_UINT_HEAP_SIZE);
+#endif
}
}
}
@@ -1190,12 +1208,15 @@ static void
insert_bif_timer(Eterm receiver, Eterm msg, ErlHeapFragment *bp, void *arg)
{
if (bp) {
- Eterm heap[3];
+ DeclareTmpHeapNoproc(heap,3);
+
+ UseTmpHeapNoproc(3);
insert_offheap(&bp->off_heap,
TIMER_REF,
(is_internal_pid(receiver)
? receiver
: TUPLE2(&heap[0], AM_process, receiver)));
+ UnUseTmpHeapNoproc(3);
}
}
@@ -1230,7 +1251,7 @@ setup_reference_table(void)
DistEntry *dep;
HashInfo hi;
int i;
- Eterm heap[3];
+ DeclareTmpHeapNoproc(heap,3);
inserted_bins = NULL;
@@ -1251,6 +1272,7 @@ setup_reference_table(void)
/* Go through the hole system, and build a table of all references
to ErlNode and DistEntry structures */
+ UseTmpHeapNoproc(3);
insert_node(erts_this_node,
SYSTEM_REF,
TUPLE2(&heap[0], AM_system, am_undefined));
@@ -1261,6 +1283,7 @@ setup_reference_table(void)
HEAP_REF,
TUPLE2(&heap[0], AM_processes, am_undefined));
#endif
+ UnUseTmpHeapNoproc(3);
/* Insert all processes */
for (i = 0; i < erts_max_processes; i++)
diff --git a/erts/emulator/beam/erl_node_tables.h b/erts/emulator/beam/erl_node_tables.h
index c48dac6219..eb759b87e9 100644
--- a/erts/emulator/beam/erl_node_tables.h
+++ b/erts/emulator/beam/erl_node_tables.h
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2001-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2001-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -61,7 +61,7 @@
#define ERTS_DE_QFLGS_ALL (ERTS_DE_QFLG_BUSY \
| ERTS_DE_QFLG_EXIT)
-#ifdef ARCH_64
+#if defined(ARCH_64) && !HALFWORD_HEAP
#define ERTS_DIST_OUTPUT_BUF_DBG_PATTERN ((Uint) 0xf713f713f713f713UL)
#else
#define ERTS_DIST_OUTPUT_BUF_DBG_PATTERN ((Uint) 0xf713f713)
diff --git a/erts/emulator/beam/erl_printf_term.c b/erts/emulator/beam/erl_printf_term.c
index 7fe3f3bca5..d9f132f067 100644
--- a/erts/emulator/beam/erl_printf_term.c
+++ b/erts/emulator/beam/erl_printf_term.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2005-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2005-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -246,7 +246,7 @@ print_term(fmtfn_t fn, void* arg, Eterm obj, long *dcount)
if (is_CP(obj)) {
PRINT_STRING(res, fn, arg, "<cp/header:");
- PRINT_POINTER(res, fn, arg, obj);
+ PRINT_POINTER(res, fn, arg, cp_val(obj));
PRINT_CHAR(res, fn, arg, '>');
return res;
}
@@ -406,7 +406,7 @@ print_term(fmtfn_t fn, void* arg, Eterm obj, long *dcount)
break;
case EXPORT_DEF:
{
- Export* ep = (Export *) (export_val(obj))[1];
+ Export* ep = *((Export **) (export_val(obj) + 1));
Atom* module = atom_tab(atom_val(ep->code[0]));
Atom* name = atom_tab(atom_val(ep->code[1]));
@@ -438,7 +438,7 @@ print_term(fmtfn_t fn, void* arg, Eterm obj, long *dcount)
break;
default:
PRINT_STRING(res, fn, arg, "<unknown:");
- PRINT_POINTER(res, fn, arg, obj);
+ PRINT_POINTER(res, fn, arg, (UWord) obj);
PRINT_CHAR(res, fn, arg, '>');
break;
}
diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c
index 996806fc75..11ca85a41c 100644
--- a/erts/emulator/beam/erl_process.c
+++ b/erts/emulator/beam/erl_process.c
@@ -91,9 +91,9 @@ do { \
#define ERTS_EMPTY_RUNQ(RQ) \
((RQ)->len == 0 && (RQ)->misc.start == NULL)
-extern Eterm beam_apply[];
-extern Eterm beam_exit[];
-extern Eterm beam_continue_exit[];
+extern BeamInstr beam_apply[];
+extern BeamInstr beam_exit[];
+extern BeamInstr beam_continue_exit[];
static Sint p_last;
static Sint p_next;
@@ -334,7 +334,7 @@ do { \
static void init_processes_bif(void);
static void save_terminating_process(Process *p);
static void exec_misc_ops(ErtsRunQueue *);
-static void print_function_from_pc(int to, void *to_arg, Eterm* x);
+static void print_function_from_pc(int to, void *to_arg, BeamInstr* x);
static int stack_element_dump(int to, void *to_arg, Process* p, Eterm* sp,
int yreg);
#ifdef ERTS_SMP
@@ -2078,9 +2078,9 @@ erts_init_scheduling(int mrq, int no_schedulers, int no_schedulers_online)
erts_aligned_run_queues = erts_alloc(ERTS_ALC_T_RUNQS,
(sizeof(ErtsAlignedRunQueue)*(n+1)));
- if ((((Uint) erts_aligned_run_queues) & ERTS_CACHE_LINE_MASK) == 0)
+ if ((((UWord) erts_aligned_run_queues) & ERTS_CACHE_LINE_MASK) == 0)
erts_aligned_run_queues = ((ErtsAlignedRunQueue *)
- ((((Uint) erts_aligned_run_queues)
+ ((((UWord) erts_aligned_run_queues)
& ~ERTS_CACHE_LINE_MASK)
+ ERTS_CACHE_LINE_SIZE));
@@ -2175,9 +2175,9 @@ erts_init_scheduling(int mrq, int no_schedulers, int no_schedulers_online)
erts_aligned_scheduler_data = erts_alloc(ERTS_ALC_T_SCHDLR_DATA,
(sizeof(ErtsAlignedSchedulerData)
*(n+1)));
- if ((((Uint) erts_aligned_scheduler_data) & ERTS_CACHE_LINE_MASK) == 0)
+ if ((((UWord) erts_aligned_scheduler_data) & ERTS_CACHE_LINE_MASK) == 0)
erts_aligned_scheduler_data = ((ErtsAlignedSchedulerData *)
- ((((Uint) erts_aligned_scheduler_data)
+ ((((UWord) erts_aligned_scheduler_data)
& ~ERTS_CACHE_LINE_MASK)
+ ERTS_CACHE_LINE_SIZE));
for (ix = 0; ix < n; ix++) {
@@ -2186,6 +2186,13 @@ erts_init_scheduling(int mrq, int no_schedulers, int no_schedulers_online)
erts_bits_init_state(&esdp->erl_bits_state);
esdp->match_pseudo_process = NULL;
esdp->free_process = NULL;
+#if HALFWORD_HEAP
+ /* Registers need to be heap allocated (correct memory range) for tracing to work */
+ esdp->save_reg = erts_alloc(ERTS_ALC_T_BEAM_REGISTER, ERTS_X_REGS_ALLOCATED * sizeof(Eterm));
+#endif
+#endif
+#if !HEAP_ON_C_STACK
+ esdp->num_tmp_heap_used = 0;
#endif
esdp->no = (Uint) ix+1;
esdp->current_process = NULL;
@@ -4481,7 +4488,7 @@ add_pend_suspend(Process *suspendee,
sizeof(ErtsPendingSuspend));
psp->next = NULL;
#ifdef DEBUG
-#ifdef ARCH_64
+#if defined(ARCH_64) && !HALFWORD_HEAP
psp->end = (ErtsPendingSuspend *) 0xdeaddeaddeaddead;
#else
psp->end = (ErtsPendingSuspend *) 0xdeaddead;
@@ -6231,10 +6238,10 @@ Process *schedule(Process *p, int calls)
erts_smp_proc_lock(p, ERTS_PROC_LOCK_MAIN|ERTS_PROC_LOCK_STATUS);
if (erts_sched_stat.enabled) {
- Uint old = ERTS_PROC_SCHED_ID(p,
+ UWord old = ERTS_PROC_SCHED_ID(p,
(ERTS_PROC_LOCK_MAIN
| ERTS_PROC_LOCK_STATUS),
- esdp->no);
+ (UWord) esdp->no);
int migrated = old && old != esdp->no;
erts_smp_spin_lock(&erts_sched_stat.lock);
@@ -6762,8 +6769,8 @@ erl_create_process(Process* parent, /* Parent of process (default group leader).
p->current = p->initial+INITIAL_MOD;
- p->i = (Eterm *) beam_apply;
- p->cp = (Eterm *) beam_apply+1;
+ p->i = (BeamInstr *) beam_apply;
+ p->cp = (BeamInstr *) beam_apply+1;
p->arg_reg = p->def_arg_reg;
p->max_arg_reg = sizeof(p->def_arg_reg)/sizeof(p->def_arg_reg[0]);
@@ -7348,7 +7355,7 @@ set_proc_exiting(Process *p, Eterm reason, ErlHeapFragment *bp)
p->freason = EXTAG_EXIT;
KILL_CATCHES(p);
cancel_timer(p);
- p->i = (Eterm *) beam_exit;
+ p->i = (BeamInstr *) beam_exit;
}
@@ -7778,9 +7785,10 @@ static void doit_exit_monitor(ErtsMonitor *mon, void *vpcontext)
erts_port_release(prt);
} else if (is_internal_pid(mon->pid)) {/* local by name or pid */
Eterm watched;
- Eterm lhp[3];
+ DeclareTmpHeapNoproc(lhp,3);
ErtsProcLocks rp_locks = (ERTS_PROC_LOCK_LINK
| ERTS_PROC_LOCKS_MSG_SEND);
+ UseTmpHeapNoproc(3);
rp = erts_pid2proc(NULL, 0, mon->pid, rp_locks);
if (rp == NULL) {
goto done;
@@ -7795,6 +7803,7 @@ static void doit_exit_monitor(ErtsMonitor *mon, void *vpcontext)
erts_queue_monitor_message(rp, &rp_locks, mon->ref, am_process,
watched, pcontext->reason);
}
+ UnUseTmpHeapNoproc(3);
/* else: demonitor while we exited, i.e. do nothing... */
erts_smp_proc_unlock(rp, rp_locks);
} else { /* external by pid or name */
@@ -8228,11 +8237,12 @@ continue_exit_process(Process *p
* Pre-build the EXIT tuple if there are any links.
*/
if (lnk) {
- Eterm tmp_heap[4];
+ DeclareTmpHeap(tmp_heap,4,p);
Eterm exit_tuple;
Uint exit_tuple_sz;
Eterm* hp;
+ UseTmpHeap(4,p);
hp = &tmp_heap[0];
exit_tuple = TUPLE3(hp, am_EXIT, p->id, reason);
@@ -8243,11 +8253,13 @@ continue_exit_process(Process *p
ExitLinkContext context = {p, reason, exit_tuple, exit_tuple_sz};
erts_sweep_links(lnk, &doit_exit_link, &context);
}
+ UnUseTmpHeap(4,p);
}
{
ExitMonitorContext context = {reason, p};
- erts_sweep_monitors(mon,&doit_exit_monitor,&context);
+ erts_sweep_monitors(mon,&doit_exit_monitor,&context); /* Allocates TmpHeap, but we
+ have none here */
}
if (scb)
@@ -8271,7 +8283,7 @@ continue_exit_process(Process *p
ASSERT(p->status == P_EXITING);
- p->i = (Eterm *) beam_continue_exit;
+ p->i = (BeamInstr *) beam_continue_exit;
if (!(curr_locks & ERTS_PROC_LOCK_STATUS)) {
erts_smp_proc_lock(p, ERTS_PROC_LOCK_STATUS);
@@ -8291,7 +8303,7 @@ continue_exit_process(Process *p
static void
timeout_proc(Process* p)
{
- p->i = (Eterm *) p->def_arg_reg[0];
+ p->i = *((BeamInstr **) (UWord) p->def_arg_reg);
p->flags |= F_TIMO;
p->flags &= ~F_INSLPQUEUE;
@@ -8390,9 +8402,9 @@ erts_program_counter_info(int to, void *to_arg, Process *p)
}
static void
-print_function_from_pc(int to, void *to_arg, Eterm* x)
+print_function_from_pc(int to, void *to_arg, BeamInstr* x)
{
- Eterm* addr = find_function_from_pc(x);
+ BeamInstr* addr = find_function_from_pc(x);
if (addr == NULL) {
if (x == beam_exit) {
erts_print(to, to_arg, "<terminate process>");
@@ -8426,7 +8438,7 @@ stack_element_dump(int to, void *to_arg, Process* p, Eterm* sp, int yreg)
}
if (is_CP(x)) {
- erts_print(to, to_arg, "Return addr %p (", (Eterm *) x);
+ erts_print(to, to_arg, "Return addr %p (", (Eterm *) EXPAND_POINTER(x));
print_function_from_pc(to, to_arg, cp_val(x));
erts_print(to, to_arg, ")\n");
yreg = 0;
@@ -9255,8 +9267,8 @@ init_processes_bif(void)
processes_trap_export.code[0] = am_erlang;
processes_trap_export.code[1] = am_processes_trap;
processes_trap_export.code[2] = 2;
- processes_trap_export.code[3] = (Eterm) em_apply_bif;
- processes_trap_export.code[4] = (Eterm) &processes_trap;
+ processes_trap_export.code[3] = (BeamInstr) em_apply_bif;
+ processes_trap_export.code[4] = (BeamInstr) &processes_trap;
#if ERTS_PROCESSES_BIF_DEBUGLEVEL >= ERTS_PROCS_DBGLVL_CHK_TERM_PROC_LIST
erts_get_emu_time(&debug_tv_start);
diff --git a/erts/emulator/beam/erl_process.h b/erts/emulator/beam/erl_process.h
index f58b6932b3..cbcdec4ba7 100644
--- a/erts/emulator/beam/erl_process.h
+++ b/erts/emulator/beam/erl_process.h
@@ -179,7 +179,7 @@ extern int erts_sched_thread_suggested_stack_size;
#ifdef DEBUG
-# ifdef ARCH_64
+# if defined(ARCH_64) && !HALFWORD_HEAP
# define ERTS_DBG_SET_INVALID_RUNQP(RQP, N) \
(*((char **) &(RQP)) = (char *) (0xdeadbeefdead0003 | ((N) << 4)))
# define ERTS_DBG_VERIFY_VALID_RUNQP(RQP) \
@@ -194,8 +194,8 @@ do { \
# define ERTS_DBG_VERIFY_VALID_RUNQP(RQP) \
do { \
ASSERT((RQP) != NULL); \
- ASSERT(((((Uint) (RQP)) & ((Uint) 1))) == ((Uint) 0)); \
- ASSERT((((Uint) (RQP)) & ~((Uint) 0xffff)) != ((Uint) 0xdead0000)); \
+ ASSERT(((((UWord) (RQP)) & ((UWord) 1))) == ((UWord) 0)); \
+ ASSERT((((UWord) (RQP)) & ~((UWord) 0xffff)) != ((UWord) 0xdead0000)); \
} while (0)
# endif
#else
@@ -344,13 +344,24 @@ struct ErtsSchedulerData_ {
* numbered registers as possible in the same cache
* line).
*/
+#if !HALFWORD_HEAP
Eterm save_reg[ERTS_X_REGS_ALLOCATED]; /* X registers */
+#else
+ Eterm *save_reg;
+#endif
FloatDef freg[MAX_REG]; /* Floating point registers. */
ethr_tid tid; /* Thread id */
struct erl_bits_state erl_bits_state; /* erl_bits.c state */
void *match_pseudo_process; /* erl_db_util.c:db_prog_match() */
Process *free_process;
#endif
+#if !HEAP_ON_C_STACK
+ Eterm tmp_heap[TMP_HEAP_SIZE];
+ int num_tmp_heap_used;
+ Eterm beam_emu_tmp_heap[BEAM_EMU_TMP_HEAP_SIZE];
+ Eterm cmp_tmp_heap[CMP_TMP_HEAP_SIZE];
+ Eterm erl_arith_tmp_heap[ERL_ARITH_TMP_HEAP_SIZE];
+#endif
Process *current_process;
Uint no; /* Scheduler number */
@@ -518,8 +529,8 @@ struct process {
unsigned max_arg_reg; /* Maximum number of argument registers available. */
Eterm def_arg_reg[6]; /* Default array for argument registers. */
- Eterm* cp; /* Continuation pointer (for threaded code). */
- Eterm* i; /* Program counter for threaded code. */
+ BeamInstr* cp; /* (untagged) Continuation pointer (for threaded code). */
+ BeamInstr* i; /* Program counter for threaded code. */
Sint catches; /* Number of catches on stack */
Sint fcalls; /*
* Number of reductions left to execute.
@@ -566,11 +577,12 @@ struct process {
Uint seq_trace_lastcnt;
Eterm seq_trace_token; /* Sequential trace token (tuple size 5 see below) */
- Eterm initial[3]; /* Initial module(0), function(1), arity(2) */
- Eterm* current; /* Current Erlang function:
+ BeamInstr initial[3]; /* Initial module(0), function(1), arity(2), often used instead
+ of pointer to funcinfo instruction, hence the BeamInstr datatype */
+ BeamInstr* current; /* Current Erlang function, part of the funcinfo:
* module(0), function(1), arity(2)
* (module and functions are tagged atoms;
- * arity an untagged integer).
+ * arity an untagged integer). BeamInstr * because it references code
*/
/*
@@ -1184,7 +1196,7 @@ erts_psd_set(Process *p, ErtsProcLocks plocks, int ix, void *data)
#endif
#define ERTS_PROC_SCHED_ID(P, L, ID) \
- ((Uint) erts_psd_set((P), (L), ERTS_PSD_SCHED_ID, (void *) (ID)))
+ ((UWord) erts_psd_set((P), (L), ERTS_PSD_SCHED_ID, (void *) (ID)))
#define ERTS_PROC_GET_DIST_ENTRY(P) \
((DistEntry *) erts_psd_get((P), ERTS_PSD_DIST_ENTRY))
@@ -1209,8 +1221,8 @@ erts_proc_get_error_handler(Process *p)
if (!val)
return am_error_handler;
else {
- ASSERT(is_atom(((Eterm) val)));
- return (Eterm) val;
+ ASSERT(is_atom(((Eterm) (UWord) val)));
+ return (Eterm) (UWord) val;
}
}
@@ -1220,13 +1232,13 @@ erts_proc_set_error_handler(Process *p, ErtsProcLocks plocks, Eterm handler)
void *old_val;
void *new_val;
ASSERT(is_atom(handler));
- new_val = handler == am_error_handler ? NULL : (void *) handler;
+ new_val = (handler == am_error_handler) ? NULL : (void *) (UWord) handler;
old_val = erts_psd_set(p, plocks, ERTS_PSD_ERROR_HANDLER, new_val);
if (!old_val)
return am_error_handler;
else {
- ASSERT(is_atom(((Eterm) old_val)));
- return (Eterm) old_val;
+ ASSERT(is_atom(((Eterm) (UWord) old_val)));
+ return (Eterm) (UWord) old_val;
}
}
diff --git a/erts/emulator/beam/erl_process_dump.c b/erts/emulator/beam/erl_process_dump.c
index 1666509c72..7a7042abe4 100644
--- a/erts/emulator/beam/erl_process_dump.c
+++ b/erts/emulator/beam/erl_process_dump.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2003-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2003-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -45,16 +45,16 @@ static void dump_dist_ext(int to, void *to_arg, ErtsDistExternal *edep);
static void dump_element_nl(int to, void *to_arg, Eterm x);
static int stack_element_dump(int to, void *to_arg, Process* p, Eterm* sp,
int yreg);
-static void print_function_from_pc(int to, void *to_arg, Eterm* x);
+static void print_function_from_pc(int to, void *to_arg, BeamInstr* x);
static void heap_dump(int to, void *to_arg, Eterm x);
static void dump_binaries(int to, void *to_arg, Binary* root);
static void dump_externally(int to, void *to_arg, Eterm term);
static Binary* all_binaries;
-extern Eterm beam_apply[];
-extern Eterm beam_exit[];
-extern Eterm beam_continue_exit[];
+extern BeamInstr beam_apply[];
+extern BeamInstr beam_exit[];
+extern BeamInstr beam_continue_exit[];
void
@@ -223,7 +223,7 @@ stack_element_dump(int to, void *to_arg, Process* p, Eterm* sp, int yreg)
}
if (is_CP(x)) {
- erts_print(to, to_arg, "SReturn addr 0x%X (", (Eterm *) x);
+ erts_print(to, to_arg, "SReturn addr 0x%X (", cp_val(x));
print_function_from_pc(to, to_arg, cp_val(x));
erts_print(to, to_arg, ")\n");
yreg = 0;
@@ -239,9 +239,9 @@ stack_element_dump(int to, void *to_arg, Process* p, Eterm* sp, int yreg)
}
static void
-print_function_from_pc(int to, void *to_arg, Eterm* x)
+print_function_from_pc(int to, void *to_arg, BeamInstr* x)
{
- Eterm* addr = find_function_from_pc(x);
+ BeamInstr* addr = find_function_from_pc(x);
if (addr == NULL) {
if (x == beam_exit) {
erts_print(to, to_arg, "<terminate process>");
@@ -273,7 +273,7 @@ heap_dump(int to, void *to_arg, Eterm x)
if (x == OUR_NIL) { /* We are done. */
return;
} if (is_CP(x)) {
- next = (Eterm *) x;
+ next = (Eterm *) EXPAND_POINTER(x);
} else if (is_list(x)) {
ptr = list_val(x);
if (ptr[0] != OUR_NIL) {
@@ -286,7 +286,7 @@ heap_dump(int to, void *to_arg, Eterm x)
ptr[1] = make_small(0);
}
x = ptr[0];
- ptr[0] = (Eterm) next;
+ ptr[0] = (Eterm) COMPRESS_POINTER(next);
next = ptr + 1;
goto again;
}
@@ -316,7 +316,7 @@ heap_dump(int to, void *to_arg, Eterm x)
ptr[0] = OUR_NIL;
} else {
x = ptr[arity];
- ptr[0] = (Eterm) next;
+ ptr[0] = (Eterm) COMPRESS_POINTER(next);
next = ptr + arity - 1;
goto again;
}
@@ -351,7 +351,7 @@ heap_dump(int to, void *to_arg, Eterm x)
Binary* val = pb->val;
if (erts_smp_atomic_xchg(&val->refc, 0) != 0) {
- val->flags = (Uint) all_binaries;
+ val->flags = (UWord) all_binaries;
all_binaries = val;
}
erts_print(to, to_arg, "Yc%X:%X:%X", val,
diff --git a/erts/emulator/beam/erl_term.c b/erts/emulator/beam/erl_term.c
index 2924abbd51..c6458a0e45 100644
--- a/erts/emulator/beam/erl_term.c
+++ b/erts/emulator/beam/erl_term.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2000-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2000-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -68,7 +68,9 @@ unsigned tag_val_def(Eterm x)
static char msg[32];
switch (x & _TAG_PRIMARY_MASK) {
- case TAG_PRIMARY_LIST: return LIST_DEF;
+ case TAG_PRIMARY_LIST:
+ ET_ASSERT(_list_precond(x),file,line);
+ return LIST_DEF;
case TAG_PRIMARY_BOXED: {
Eterm hdr = *boxed_val(x);
ET_ASSERT(is_header(hdr),file,line);
@@ -103,7 +105,7 @@ unsigned tag_val_def(Eterm x)
break;
}
}
- sprintf(msg, "tag_val_def: %#lx", x);
+ sprintf(msg, "tag_val_def: %#lx", (unsigned long) x);
et_abort(msg, file, line);
#undef file
#undef line
@@ -121,12 +123,12 @@ FUNTY checked_##FUN(ARGTY x, const char *file, unsigned line) \
return _unchecked_##FUN(x); \
}
-ET_DEFINE_CHECKED(Eterm,make_boxed,Eterm*,_is_aligned);
+ET_DEFINE_CHECKED(Eterm,make_boxed,Eterm*,_is_taggable_pointer);
ET_DEFINE_CHECKED(int,is_boxed,Eterm,!is_header);
-ET_DEFINE_CHECKED(Eterm*,boxed_val,Eterm,is_boxed);
-ET_DEFINE_CHECKED(Eterm,make_list,Eterm*,_is_aligned);
+ET_DEFINE_CHECKED(Eterm*,boxed_val,Eterm,_boxed_precond);
+ET_DEFINE_CHECKED(Eterm,make_list,Eterm*,_is_taggable_pointer);
ET_DEFINE_CHECKED(int,is_not_list,Eterm,!is_header);
-ET_DEFINE_CHECKED(Eterm*,list_val,Eterm,is_list);
+ET_DEFINE_CHECKED(Eterm*,list_val,Eterm,_list_precond);
ET_DEFINE_CHECKED(Uint,unsigned_val,Eterm,is_small);
ET_DEFINE_CHECKED(Sint,signed_val,Eterm,is_small);
ET_DEFINE_CHECKED(Uint,atom_val,Eterm,is_atom);
@@ -163,8 +165,8 @@ ET_DEFINE_CHECKED(Uint32*,external_ref_data,Eterm,is_external_ref);
ET_DEFINE_CHECKED(struct erl_node_*,external_ref_node,Eterm,is_external_ref);
ET_DEFINE_CHECKED(Eterm*,export_val,Eterm,is_export);
-ET_DEFINE_CHECKED(Eterm,make_cp,Uint*,_is_aligned);
-ET_DEFINE_CHECKED(Uint*,cp_val,Eterm,is_CP);
+ET_DEFINE_CHECKED(Eterm,make_cp,UWord *,_is_taggable_pointer);
+ET_DEFINE_CHECKED(UWord *,cp_val,Eterm,is_CP);
ET_DEFINE_CHECKED(Uint,catch_val,Eterm,is_catch);
ET_DEFINE_CHECKED(Uint,x_reg_offset,Uint,_is_xreg);
ET_DEFINE_CHECKED(Uint,y_reg_offset,Uint,_is_yreg);
diff --git a/erts/emulator/beam/erl_term.h b/erts/emulator/beam/erl_term.h
index a6596558fa..3a8c30fe6a 100644
--- a/erts/emulator/beam/erl_term.h
+++ b/erts/emulator/beam/erl_term.h
@@ -20,6 +20,32 @@
#ifndef __ERL_TERM_H
#define __ERL_TERM_H
+#include "sys.h" /* defines HALFWORD_HEAP */
+
+#if HALFWORD_HEAP
+# define HEAP_ON_C_STACK 0
+# if HALFWORD_ASSERT
+# ifdef ET_DEBUG
+# undef ET_DEBUG
+# endif
+# define ET_DEBUG 1
+# endif
+# if 1
+# define CHECK_POINTER_MASK 0xFFFFFFFF00000000UL
+# define COMPRESS_POINTER(APointer) ((Eterm) (UWord) (APointer))
+# define EXPAND_POINTER(AnEterm) ((UWord) (AnEterm))
+# else
+# define CHECK_POINTER_MASK 0x0UL
+# define COMPRESS_POINTER(AnUint) (AnUint)
+# define EXPAND_POINTER(APointer) (APointer)
+# endif
+#else
+# define HEAP_ON_C_STACK 1
+# define CHECK_POINTER_MASK 0x0UL
+# define COMPRESS_POINTER(AnUint) (AnUint)
+# define EXPAND_POINTER(APointer) (APointer)
+#endif
+
struct erl_node_; /* Declared in erl_node_tables.h */
/*
@@ -158,9 +184,16 @@ struct erl_node_; /* Declared in erl_node_tables.h */
/* boxed object access methods */
+#if HALFWORD_HEAP
+#define _is_taggable_pointer(x) (((UWord)(x) & (CHECK_POINTER_MASK | 0x3)) == 0)
+#define _boxed_precond(x) (is_boxed(x))
+#else
+#define _is_taggable_pointer(x) (((Uint)(x) & 0x3) == 0)
+#define _boxed_precond(x) (is_boxed(x))
+#endif
#define _is_aligned(x) (((Uint)(x) & 0x3) == 0)
-#define _unchecked_make_boxed(x) ((Uint)(x) + TAG_PRIMARY_BOXED)
-_ET_DECLARE_CHECKED(Eterm,make_boxed,Eterm*)
+#define _unchecked_make_boxed(x) ((Uint) COMPRESS_POINTER(x) + TAG_PRIMARY_BOXED)
+_ET_DECLARE_CHECKED(Eterm,make_boxed,Eterm*);
#define make_boxed(x) _ET_APPLY(make_boxed,(x))
#if 1
#define _is_not_boxed(x) ((x) & (_TAG_PRIMARY_MASK-TAG_PRIMARY_BOXED))
@@ -170,13 +203,13 @@ _ET_DECLARE_CHECKED(int,is_boxed,Eterm)
#else
#define is_boxed(x) (((x) & _TAG_PRIMARY_MASK) == TAG_PRIMARY_BOXED)
#endif
-#define _unchecked_boxed_val(x) ((Eterm*)((x) - TAG_PRIMARY_BOXED))
-_ET_DECLARE_CHECKED(Eterm*,boxed_val,Eterm)
+#define _unchecked_boxed_val(x) ((Eterm*) EXPAND_POINTER(((x) - TAG_PRIMARY_BOXED)))
+_ET_DECLARE_CHECKED(Eterm*,boxed_val,Eterm);
#define boxed_val(x) _ET_APPLY(boxed_val,(x))
/* cons cell ("list") access methods */
-#define _unchecked_make_list(x) ((Uint)(x) + TAG_PRIMARY_LIST)
-_ET_DECLARE_CHECKED(Eterm,make_list,Eterm*)
+#define _unchecked_make_list(x) ((Uint) COMPRESS_POINTER(x) + TAG_PRIMARY_LIST)
+_ET_DECLARE_CHECKED(Eterm,make_list,Eterm*);
#define make_list(x) _ET_APPLY(make_list,(x))
#if 1
#define _unchecked_is_not_list(x) ((x) & (_TAG_PRIMARY_MASK-TAG_PRIMARY_LIST))
@@ -187,8 +220,13 @@ _ET_DECLARE_CHECKED(int,is_not_list,Eterm)
#define is_list(x) (((x) & _TAG_PRIMARY_MASK) == TAG_PRIMARY_LIST)
#define is_not_list(x) (!is_list((x)))
#endif
-#define _unchecked_list_val(x) ((Eterm*)((x) - TAG_PRIMARY_LIST))
-_ET_DECLARE_CHECKED(Eterm*,list_val,Eterm)
+#if HALFWORD_HEAP
+#define _list_precond(x) (is_list(x))
+#else
+#define _list_precond(x) (is_list(x))
+#endif
+#define _unchecked_list_val(x) ((Eterm*) EXPAND_POINTER((x) - TAG_PRIMARY_LIST))
+_ET_DECLARE_CHECKED(Eterm*,list_val,Eterm);
#define list_val(x) _ET_APPLY(list_val,(x))
#define CONS(hp, car, cdr) \
@@ -198,13 +236,13 @@ _ET_DECLARE_CHECKED(Eterm*,list_val,Eterm)
#define CDR(x) ((x)[1])
/* generic tagged pointer (boxed or list) access methods */
-#define _unchecked_ptr_val(x) ((Eterm*)((x) & ~((Uint) 0x3)))
+#define _unchecked_ptr_val(x) ((Eterm*) EXPAND_POINTER((x) & ~((Uint) 0x3)))
#define ptr_val(x) _unchecked_ptr_val((x)) /*XXX*/
#define _unchecked_offset_ptr(x,offs) ((x)+((offs)*sizeof(Eterm)))
#define offset_ptr(x,offs) _unchecked_offset_ptr(x,offs) /*XXX*/
/* fixnum ("small") access methods */
-#if defined(ARCH_64)
+#if defined(ARCH_64) && !HALFWORD_HEAP
#define SMALL_BITS (64-4)
#define SMALL_DIGITS (17)
#else
@@ -329,7 +367,11 @@ _ET_DECLARE_CHECKED(Eterm*,fun_val,Eterm)
_ET_DECLARE_CHECKED(Eterm*,export_val,Eterm)
#define export_val(x) _ET_APPLY(export_val,(x))
#define is_export_header(x) ((x) == HEADER_EXPORT)
+#if HALFWORD_HEAP
+#define HEADER_EXPORT _make_header(2,_TAG_HEADER_EXPORT)
+#else
#define HEADER_EXPORT _make_header(1,_TAG_HEADER_EXPORT)
+#endif
/* bignum access methods */
#define make_pos_bignum_header(sz) _make_header((sz),_TAG_HEADER_POS_BIG)
@@ -353,7 +395,7 @@ _ET_DECLARE_CHECKED(Eterm*,big_val,Eterm)
#define big_val(x) _ET_APPLY(big_val,(x))
/* flonum ("float") access methods */
-#ifdef ARCH_64
+#if defined(ARCH_64) && !HALFWORD_HEAP
#define HEADER_FLONUM _make_header(1,_TAG_HEADER_FLOAT)
#else
#define HEADER_FLONUM _make_header(2,_TAG_HEADER_FLOAT)
@@ -374,12 +416,12 @@ typedef union float_def
byte fb[sizeof(ieee754_8)];
Uint16 fs[sizeof(ieee754_8) / sizeof(Uint16)];
Uint32 fw[sizeof(ieee754_8) / sizeof(Uint32)];
-#ifdef ARCH_64
+#if defined(ARCH_64) && !HALFWORD_HEAP
Uint fdw;
#endif
} FloatDef;
-#ifdef ARCH_64
+#if defined(ARCH_64) && !HALFWORD_HEAP
#define GET_DOUBLE(x, f) (f).fdw = *(float_val(x)+1)
#define PUT_DOUBLE(f, x) *(x) = HEADER_FLONUM, \
@@ -679,7 +721,7 @@ _ET_DECLARE_CHECKED(struct erl_node_*,internal_port_node,Eterm)
#define ERTS_MAX_REF_NUMBERS 3
#define ERTS_REF_NUMBERS ERTS_MAX_REF_NUMBERS
-#ifdef ARCH_64
+#if defined(ARCH_64) && !HALFWORD_HEAP
# define ERTS_REF_WORDS (ERTS_REF_NUMBERS/2 + 1)
# define ERTS_REF_32BIT_WORDS (ERTS_REF_NUMBERS+1)
#else
@@ -701,7 +743,7 @@ typedef struct {
#define make_ref_thing_header(DW) \
_make_header((DW)+REF_THING_HEAD_SIZE-1,_TAG_HEADER_REF)
-#ifdef ARCH_64
+#if defined(ARCH_64) && !HALFWORD_HEAP
/*
* Ref layout on a 64-bit little endian machine:
@@ -807,6 +849,11 @@ _ET_DECLARE_CHECKED(struct erl_node_*,internal_ref_node,Eterm)
*
*/
+/* XXX:PaN - this structure is not perfect for halfword heap, it takes
+ a lot of memory due to padding, and the array will not begin at the end of the
+ structure, as otherwise expected. Be sure to access data.ui32 array and not try
+ to do pointer manipulation on an Eterm * to reach the actual data... */
+
typedef struct external_thing_ {
/* ----+ */
Eterm header; /* | */
@@ -944,15 +991,15 @@ _ET_DECLARE_CHECKED(struct erl_node_*,external_ref_node,Eterm)
#error "fix yer arch, like"
#endif
-#define _unchecked_make_cp(x) ((Eterm)(x))
-_ET_DECLARE_CHECKED(Eterm,make_cp,Uint*)
+#define _unchecked_make_cp(x) ((Eterm) COMPRESS_POINTER(x))
+_ET_DECLARE_CHECKED(Eterm,make_cp,BeamInstr*);
#define make_cp(x) _ET_APPLY(make_cp,(x))
#define is_not_CP(x) ((x) & _CPMASK)
#define is_CP(x) (!is_not_CP(x))
-#define _unchecked_cp_val(x) ((Uint*)(x))
-_ET_DECLARE_CHECKED(Uint*,cp_val,Eterm)
+#define _unchecked_cp_val(x) ((BeamInstr*) EXPAND_POINTER(x))
+_ET_DECLARE_CHECKED(BeamInstr*,cp_val,Eterm);
#define cp_val(x) _ET_APPLY(cp_val,(x))
#define make_catch(x) (((x) << _TAG_IMMED2_SIZE) | _TAG_IMMED2_CATCH)
diff --git a/erts/emulator/beam/erl_trace.c b/erts/emulator/beam/erl_trace.c
index 2842c2361a..8addfcf5ad 100644
--- a/erts/emulator/beam/erl_trace.c
+++ b/erts/emulator/beam/erl_trace.c
@@ -397,11 +397,13 @@ WRITE_SYS_MSG_TO_PORT(Eterm unused_to,
*/
static void
do_send_schedfix_to_port(Port *trace_port, Eterm pid, Eterm timestamp) {
- Eterm local_heap[4+5+5];
+#define LOCAL_HEAP_SIZE (4+5+5)
+ DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
Eterm message;
Eterm *hp;
Eterm mfarity;
+ UseTmpHeapNoproc(LOCAL_HEAP_SIZE);
ASSERT(is_pid(pid));
ASSERT(is_tuple(timestamp));
ASSERT(*tuple_val(timestamp) == make_arityval(3));
@@ -426,6 +428,8 @@ do_send_schedfix_to_port(Port *trace_port, Eterm pid, Eterm timestamp) {
pid,
SYS_MSG_TYPE_UNDEFINED,
message);
+ UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+#undef LOCAL_HEAP_SIZE
}
#endif
@@ -442,7 +446,9 @@ send_to_port(Process *c_p, Eterm message,
Eterm *tracer_pid, Uint *tracee_flags) {
Port* trace_port;
#ifndef ERTS_SMP
- Eterm ts, local_heap[4], *hp;
+#define LOCAL_HEAP_SIZE (4)
+ Eterm ts, *hp;
+ DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
#endif
ASSERT(is_internal_port(*tracer_pid));
@@ -486,6 +492,8 @@ send_to_port(Process *c_p, Eterm message,
* (e.g. getting_linked) need not be the current process. That other
* process might not have timestamps enabled.
*/
+ UseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+
if (*tracee_flags & F_TIMESTAMP) {
ASSERT(is_tuple(message));
hp = tuple_val(message);
@@ -522,6 +530,8 @@ send_to_port(Process *c_p, Eterm message,
*/
do_send_schedfix_to_port(trace_port, c_p->id, ts);
}
+ UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+#undef LOCAL_HEAP_SIZE
#endif
}
@@ -589,7 +599,10 @@ seq_trace_send_to_port(Process *c_p,
{
Port* trace_port;
#ifndef ERTS_SMP
- Eterm ts, local_heap[4], *hp;
+ Eterm ts, *hp;
+#define LOCAL_HEAP_SIZE (4)
+ DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
+ UseTmpHeapNoproc(LOCAL_HEAP_SIZE);
#endif
ASSERT(is_internal_port(seq_tracer));
@@ -607,6 +620,9 @@ seq_trace_send_to_port(Process *c_p,
if (INVALID_TRACER_PORT(trace_port, seq_tracer)) {
invalid_tracer_port:
system_seq_tracer = am_false;
+#ifndef ERTS_SMP
+ UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+#endif
return;
}
@@ -620,6 +636,7 @@ seq_trace_send_to_port(Process *c_p,
message);
#ifndef ERTS_SMP
+ UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE);
return;
}
/* Make a fake schedule only if the current process is traced
@@ -660,6 +677,8 @@ seq_trace_send_to_port(Process *c_p,
*/
do_send_schedfix_to_port(trace_port, c_p->id, ts);
}
+ UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+#undef LOCAL_HEAP_SIZE
#endif
}
@@ -719,7 +738,8 @@ send_to_tracer(Process *tracee,
static void
trace_sched_aux(Process *p, Eterm what, int never_fake_sched)
{
- Eterm local_heap[5+4+1+TS_HEAP_WORDS];
+#define LOCAL_HEAP_SIZE (5+4+1+TS_HEAP_WORDS)
+ DeclareTmpHeap(local_heap,LOCAL_HEAP_SIZE,p);
Eterm tmp, mess, *hp;
ErlHeapFragment *bp = NULL;
ErlOffHeap *off_heap;
@@ -768,8 +788,10 @@ trace_sched_aux(Process *p, Eterm what, int never_fake_sched)
curr_func = p->current != NULL;
}
+ UseTmpHeap(LOCAL_HEAP_SIZE,p);
+
if (to_port)
- hp = &local_heap[0];
+ hp = local_heap;
else {
Uint size = 5;
if (curr_func)
@@ -802,6 +824,8 @@ trace_sched_aux(Process *p, Eterm what, int never_fake_sched)
}
send_to_tracer(p, tracer_ref, mess, &hp, bp, no_fake_sched);
+ UnUseTmpHeap(LOCAL_HEAP_SIZE,p);
+#undef LOCAL_HEAP_SIZE
}
/* Send {trace_ts, Pid, What, {Mod, Func, Arity}, Timestamp}
@@ -848,7 +872,10 @@ trace_send(Process *p, Eterm to, Eterm msg)
}
if (is_internal_port(p->tracer_proc)) {
- Eterm local_heap[11];
+#define LOCAL_HEAP_SIZE (11)
+ DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
+ UseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+
hp = local_heap;
mess = TUPLE5(hp, am_trace, p->id, operation, msg, to);
hp += 6;
@@ -857,6 +884,8 @@ trace_send(Process *p, Eterm to, Eterm msg)
hp = patch_ts(mess, hp);
}
send_to_port(p, mess, &p->tracer_proc, &p->trace_flags);
+ UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+#undef LOCAL_HEAP_SIZE
erts_smp_mtx_unlock(&smq_mtx);
} else {
Uint need;
@@ -908,7 +937,10 @@ trace_receive(Process *rp, Eterm msg)
Eterm* hp;
if (is_internal_port(rp->tracer_proc)) {
- Eterm local_heap[10];
+#define LOCAL_HEAP_SIZE (10)
+ DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
+ UseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+
hp = local_heap;
mess = TUPLE4(hp, am_trace, rp->id, am_receive, msg);
hp += 5;
@@ -917,6 +949,8 @@ trace_receive(Process *rp, Eterm msg)
hp = patch_ts(mess, hp);
}
send_to_port(rp, mess, &rp->tracer_proc, &rp->trace_flags);
+ UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+#undef LOCAL_HEAP_SIZE
erts_smp_mtx_unlock(&smq_mtx);
} else {
Uint hsz;
@@ -1018,7 +1052,10 @@ seq_trace_output_generic(Eterm token, Eterm msg, Uint type,
}
if (is_internal_port(seq_tracer)) {
- Eterm local_heap[64];
+#define LOCAL_HEAP_SIZE (64)
+ DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
+ UseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+
hp = local_heap;
label = SEQ_TRACE_T_LABEL(token);
lastcnt_serial = TUPLE2(hp, SEQ_TRACE_T_LASTCNT(token),
@@ -1043,6 +1080,8 @@ seq_trace_output_generic(Eterm token, Eterm msg, Uint type,
mess = TUPLE4(hp, am_seq_trace, label, mess, ts);
seq_trace_send_to_port(process, seq_tracer, mess, ts);
}
+ UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+#undef LOCAL_HEAP_SIZE
erts_smp_mtx_unlock(&smq_mtx);
} else {
#ifndef ERTS_SMP
@@ -1143,14 +1182,18 @@ seq_trace_output_generic(Eterm token, Eterm msg, Uint type,
* or {trace, Pid, return_to, {Mod, Func, Arity}}
*/
void
-erts_trace_return_to(Process *p, Uint *pc)
+erts_trace_return_to(Process *p, BeamInstr *pc)
{
+#define LOCAL_HEAP_SIZE (4+5+5)
Eterm* hp;
Eterm mfa;
Eterm mess;
- Eterm local_heap[4+5+5];
+ DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
- Eterm *code_ptr = find_function_from_pc(pc);
+ BeamInstr *code_ptr = find_function_from_pc(pc);
+
+
+ UseTmpHeapNoproc(LOCAL_HEAP_SIZE);
hp = local_heap;
@@ -1196,6 +1239,8 @@ erts_trace_return_to(Process *p, Uint *pc)
mess = copy_struct(mess, size, &hp, off_heap);
ERTS_ENQ_TRACE_MSG(p->id, tracer_ref, mess, bp);
}
+ UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+#undef LOCAL_HEAP_SIZE
erts_smp_mtx_unlock(&smq_mtx);
}
@@ -1204,7 +1249,7 @@ erts_trace_return_to(Process *p, Uint *pc)
* or {trace, Pid, return_from, {Mod, Name, Arity}, Retval}
*/
void
-erts_trace_return(Process* p, Eterm* fi, Eterm retval, Eterm *tracer_pid)
+erts_trace_return(Process* p, BeamInstr* fi, Eterm retval, Eterm *tracer_pid)
{
Eterm* hp;
Eterm mfa;
@@ -1262,7 +1307,9 @@ erts_trace_return(Process* p, Eterm* fi, Eterm retval, Eterm *tracer_pid)
arity = fi[2];
if (is_internal_port(*tracer_pid)) {
- Eterm local_heap[4+6+5];
+#define LOCAL_HEAP_SIZE (4+6+5)
+ DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
+ UseTmpHeapNoproc(LOCAL_HEAP_SIZE);
hp = local_heap;
mfa = TUPLE3(hp, mod, name, make_small(arity));
hp += 4;
@@ -1273,6 +1320,8 @@ erts_trace_return(Process* p, Eterm* fi, Eterm retval, Eterm *tracer_pid)
hp = patch_ts(mess, hp);
}
send_to_port(p, mess, tracer_pid, tracee_flags);
+ UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+#undef LOCAL_HEAP_SIZE
erts_smp_mtx_unlock(&smq_mtx);
} else {
ErlHeapFragment *bp;
@@ -1331,7 +1380,7 @@ erts_trace_return(Process* p, Eterm* fi, Eterm retval, Eterm *tracer_pid)
* Where Class is atomic but Value is any term.
*/
void
-erts_trace_exception(Process* p, Eterm mfa[3], Eterm class, Eterm value,
+erts_trace_exception(Process* p, BeamInstr mfa[3], Eterm class, Eterm value,
Eterm *tracer_pid)
{
Eterm* hp;
@@ -1385,21 +1434,26 @@ erts_trace_exception(Process* p, Eterm mfa[3], Eterm class, Eterm value,
}
if (is_internal_port(*tracer_pid)) {
- Eterm local_heap[4+3+6+5];
+#define LOCAL_HEAP_SIZE (4+3+6+5)
+ DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
+ UseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+
hp = local_heap;
- mfa_tuple = TUPLE3(hp, mfa[0], mfa[1], make_small(mfa[2]));
+ mfa_tuple = TUPLE3(hp, (Eterm) mfa[0], (Eterm) mfa[1], make_small((Eterm)mfa[2]));
hp += 4;
cv = TUPLE2(hp, class, value);
hp += 3;
mess = TUPLE5(hp, am_trace, p->id, am_exception_from, mfa_tuple, cv);
hp += 6;
- ASSERT((hp - local_heap)*sizeof(*hp) <= sizeof(local_heap));
+ ASSERT((hp - local_heap) <= LOCAL_HEAP_SIZE);
erts_smp_mtx_lock(&smq_mtx);
if (*tracee_flags & F_TIMESTAMP) {
hp = patch_ts(mess, hp); /* hp += 5 */
- ASSERT((hp - local_heap)*sizeof(*hp) == sizeof(local_heap));
+ ASSERT((hp - local_heap) == LOCAL_HEAP_SIZE);
}
send_to_port(p, mess, tracer_pid, tracee_flags);
+ UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+#undef LOCAL_HEAP_SIZE
erts_smp_mtx_unlock(&smq_mtx);
} else {
ErlHeapFragment *bp;
@@ -1431,7 +1485,7 @@ erts_trace_exception(Process* p, Eterm mfa[3], Eterm class, Eterm value,
* Build the trace tuple and put it into receive queue of the tracer process.
*/
- mfa_tuple = TUPLE3(hp, mfa[0], mfa[1], make_small(mfa[2]));
+ mfa_tuple = TUPLE3(hp, (Eterm) mfa[0], (Eterm) mfa[1], make_small((Eterm) mfa[2]));
hp += 4;
value = copy_struct(value, value_size, &hp, off_heap);
cv = TUPLE2(hp, class, value);
@@ -1468,7 +1522,7 @@ erts_trace_exception(Process* p, Eterm mfa[3], Eterm class, Eterm value,
* if it is a pid or port we do a meta trace.
*/
Uint32
-erts_call_trace(Process* p, Eterm mfa[3], Binary *match_spec,
+erts_call_trace(Process* p, BeamInstr mfa[3], Binary *match_spec,
Eterm* args, int local, Eterm *tracer_pid)
{
Eterm* hp;
@@ -1483,7 +1537,8 @@ erts_call_trace(Process* p, Eterm mfa[3], Binary *match_spec,
Eterm tracee;
#endif
Eterm transformed_args[MAX_ARG];
- ErlSubBin sub_bin_heap;
+ DeclareTmpHeap(sub_bin_heap_et,ERL_SUB_BIN_SIZE,p);
+ ErlSubBin *sub_bin_heap = (ErlSubBin *) sub_bin_heap_et;
ASSERT(tracer_pid);
if (*tracer_pid == am_true) {
@@ -1534,19 +1589,20 @@ erts_call_trace(Process* p, Eterm mfa[3], Binary *match_spec,
* such as size_object() and copy_struct(), we must make sure that we
* temporarily convert any match contexts to sub binaries.
*/
- arity = mfa[2];
+ arity = (Eterm) mfa[2];
+ UseTmpHeap(ERL_SUB_BIN_SIZE,p);
#ifdef DEBUG
- sub_bin_heap.thing_word = 0;
+ sub_bin_heap->thing_word = 0;
#endif
for (i = 0; i < arity; i++) {
Eterm arg = args[i];
if (is_boxed(arg) && header_is_bin_matchstate(*boxed_val(arg))) {
ErlBinMatchState* ms = (ErlBinMatchState *) boxed_val(arg);
ErlBinMatchBuffer* mb = &ms->mb;
- ErlSubBin* sb = &sub_bin_heap;
+ ErlSubBin* sb = sub_bin_heap;
Uint bit_size;
- ASSERT(sub_bin_heap.thing_word == 0); /* At most one of match context */
+ ASSERT(sub_bin_heap->thing_word == 0); /* At most one of match context */
bit_size = mb->size - mb->offset;
sb->thing_word = HEADER_SUB_BIN;
@@ -1564,7 +1620,12 @@ erts_call_trace(Process* p, Eterm mfa[3], Binary *match_spec,
args = transformed_args;
if (is_internal_port(*tracer_pid)) {
+#if HEAP_ON_C_STACK
Eterm local_heap[64+MAX_ARG];
+#else
+ Eterm *local_heap = erts_alloc(ERTS_ALC_T_TEMP_TERM,
+ sizeof(Eterm)*(64+MAX_ARG));
+#endif
hp = local_heap;
if (!erts_is_valid_tracer_port(*tracer_pid)) {
@@ -1579,6 +1640,10 @@ erts_call_trace(Process* p, Eterm mfa[3], Binary *match_spec,
if (is_not_nil(tracee))
erts_smp_proc_unlock(p, ERTS_PROC_LOCKS_ALL_MINOR);
#endif
+#if !HEAP_ON_C_STACK
+ erts_free(ERTS_ALC_T_TEMP_TERM,local_heap);
+#endif
+ UnUseTmpHeap(ERL_SUB_BIN_SIZE,p);
return 0;
}
@@ -1605,6 +1670,10 @@ erts_call_trace(Process* p, Eterm mfa[3], Binary *match_spec,
&return_flags);
if (is_non_value(pam_result)) {
erts_match_set_release_result(p);
+#if !HEAP_ON_C_STACK
+ erts_free(ERTS_ALC_T_TEMP_TERM,local_heap);
+#endif
+ UnUseTmpHeap(ERL_SUB_BIN_SIZE,p);
return 0;
}
}
@@ -1612,16 +1681,28 @@ erts_call_trace(Process* p, Eterm mfa[3], Binary *match_spec,
/* Meta trace */
if (pam_result == am_false) {
erts_match_set_release_result(p);
+#if !HEAP_ON_C_STACK
+ erts_free(ERTS_ALC_T_TEMP_TERM,local_heap);
+#endif
+ UnUseTmpHeap(ERL_SUB_BIN_SIZE,p);
return return_flags;
}
} else {
/* Non-meta trace */
if (*tracee_flags & F_TRACE_SILENT) {
erts_match_set_release_result(p);
+#if !HEAP_ON_C_STACK
+ erts_free(ERTS_ALC_T_TEMP_TERM,local_heap);
+#endif
+ UnUseTmpHeap(ERL_SUB_BIN_SIZE,p);
return 0;
}
if (pam_result == am_false) {
erts_match_set_release_result(p);
+#if !HEAP_ON_C_STACK
+ erts_free(ERTS_ALC_T_TEMP_TERM,local_heap);
+#endif
+ UnUseTmpHeap(ERL_SUB_BIN_SIZE,p);
return return_flags;
}
if (local && (*tracee_flags & F_TRACE_RETURN_TO)) {
@@ -1644,7 +1725,7 @@ erts_call_trace(Process* p, Eterm mfa[3], Binary *match_spec,
hp += 2;
}
}
- mfa_tuple = TUPLE3(hp, mfa[0], mfa[1], mfa_tuple);
+ mfa_tuple = TUPLE3(hp, (Eterm) mfa[0], (Eterm) mfa[1], mfa_tuple);
hp += 4;
/*
@@ -1664,6 +1745,10 @@ erts_call_trace(Process* p, Eterm mfa[3], Binary *match_spec,
send_to_port(p, mess, tracer_pid, tracee_flags);
erts_smp_mtx_unlock(&smq_mtx);
erts_match_set_release_result(p);
+#if !HEAP_ON_C_STACK
+ erts_free(ERTS_ALC_T_TEMP_TERM,local_heap);
+#endif
+ UnUseTmpHeap(ERL_SUB_BIN_SIZE,p);
return *tracer_pid == NIL ? 0 : return_flags;
} else {
@@ -1706,6 +1791,7 @@ erts_call_trace(Process* p, Eterm mfa[3], Binary *match_spec,
if (is_not_nil(tracee))
erts_smp_proc_unlock(p, ERTS_PROC_LOCKS_ALL_MINOR);
#endif
+ UnUseTmpHeap(ERL_SUB_BIN_SIZE,p);
return 0;
}
@@ -1731,6 +1817,7 @@ erts_call_trace(Process* p, Eterm mfa[3], Binary *match_spec,
&return_flags);
if (is_non_value(pam_result)) {
erts_match_set_release_result(p);
+ UnUseTmpHeap(ERL_SUB_BIN_SIZE,p);
return 0;
}
}
@@ -1738,16 +1825,19 @@ erts_call_trace(Process* p, Eterm mfa[3], Binary *match_spec,
/* Meta trace */
if (pam_result == am_false) {
erts_match_set_release_result(p);
+ UnUseTmpHeap(ERL_SUB_BIN_SIZE,p);
return return_flags;
}
} else {
/* Non-meta trace */
if (*tracee_flags & F_TRACE_SILENT) {
erts_match_set_release_result(p);
+ UnUseTmpHeap(ERL_SUB_BIN_SIZE,p);
return 0;
}
if (pam_result == am_false) {
erts_match_set_release_result(p);
+ UnUseTmpHeap(ERL_SUB_BIN_SIZE,p);
return return_flags;
}
if (local && (*tracee_flags & F_TRACE_RETURN_TO)) {
@@ -1798,7 +1888,7 @@ erts_call_trace(Process* p, Eterm mfa[3], Binary *match_spec,
hp += 2;
}
}
- mfa_tuple = TUPLE3(hp, mfa[0], mfa[1], mfa_tuple);
+ mfa_tuple = TUPLE3(hp, (Eterm) mfa[0], (Eterm) mfa[1], mfa_tuple);
hp += 4;
/*
@@ -1831,6 +1921,7 @@ erts_call_trace(Process* p, Eterm mfa[3], Binary *match_spec,
ASSERT(hp == limit);
ERTS_ENQ_TRACE_MSG(tracee, tracer_ref, mess, bp);
erts_smp_mtx_unlock(&smq_mtx);
+ UnUseTmpHeap(ERL_SUB_BIN_SIZE,p);
return return_flags;
}
}
@@ -1851,7 +1942,10 @@ trace_proc(Process *c_p, Process *t_p, Eterm what, Eterm data)
int need;
if (is_internal_port(t_p->tracer_proc)) {
- Eterm local_heap[5+5];
+#define LOCAL_HEAP_SIZE (5+5)
+ DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
+ UseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+
hp = local_heap;
mess = TUPLE4(hp, am_trace, t_p->id, what, data);
hp += 5;
@@ -1868,6 +1962,8 @@ trace_proc(Process *c_p, Process *t_p, Eterm what, Eterm data)
c_p,
#endif
mess, &t_p->tracer_proc, &t_p->trace_flags);
+ UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+#undef LOCAL_HEAP_SIZE
erts_smp_mtx_unlock(&smq_mtx);
} else {
Eterm tmp;
@@ -1919,7 +2015,10 @@ trace_proc_spawn(Process *p, Eterm pid,
Eterm* hp;
if (is_internal_port(p->tracer_proc)) {
- Eterm local_heap[4+6+5];
+#define LOCAL_HEAP_SIZE (4+6+5)
+ DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
+ UseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+
hp = local_heap;
mfa = TUPLE3(hp, mod, func, args);
hp += 4;
@@ -1930,6 +2029,8 @@ trace_proc_spawn(Process *p, Eterm pid,
hp = patch_ts(mess, hp);
}
send_to_port(p, mess, &p->tracer_proc, &p->trace_flags);
+ UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+#undef LOCAL_HEAP_SIZE
erts_smp_mtx_unlock(&smq_mtx);
} else {
Eterm tmp;
@@ -1991,7 +2092,7 @@ void save_calls(Process *p, Export *e)
*/
Eterm
erts_bif_trace(int bif_index, Process* p,
- Eterm arg1, Eterm arg2, Eterm arg3, Uint *I)
+ Eterm arg1, Eterm arg2, Eterm arg3, BeamInstr *I)
{
Eterm result;
int meta = !!(erts_bif_trace_flags[bif_index] & BIF_TRACE_AS_META);
@@ -2005,10 +2106,10 @@ erts_bif_trace(int bif_index, Process* p,
* no tracing will occur. Doing the whole else branch will
* also do nothing, only slower.
*/
- Eterm (*func)(Process*, Eterm, Eterm, Eterm, Uint*) = bif_table[bif_index].f;
+ Eterm (*func)(Process*, Eterm, Eterm, Eterm, BeamInstr*) = bif_table[bif_index].f;
result = func(p, arg1, arg2, arg3, I);
} else {
- Eterm (*func)(Process*, Eterm, Eterm, Eterm, Uint*);
+ Eterm (*func)(Process*, Eterm, Eterm, Eterm, BeamInstr*);
Export* ep = bif_export[bif_index];
Uint32 flags = 0, flags_meta = 0;
int global = !!(erts_bif_trace_flags[bif_index] & BIF_TRACE_AS_GLOBAL);
@@ -2017,16 +2118,9 @@ erts_bif_trace(int bif_index, Process* p,
int applying = (I == &(ep->code[3])); /* Yup, the apply code for a bif
* is actually in the
* export entry */
- Eterm *cp = p->cp;
+ BeamInstr *cp = p->cp;
-#ifndef _OSE_
Eterm args[3] = {arg1, arg2, arg3};
-#else
- Eterm args[3];
- args[0] = arg1;
- args[1] = arg2;
- args[2] = arg3;
-#endif
/*
* Make continuation pointer OK, it is not during direct BIF calls,
@@ -2056,12 +2150,11 @@ erts_bif_trace(int bif_index, Process* p,
Eterm *cpp;
/* Maybe advance cp to skip trace stack frames */
for (cpp = p->stop; ; cp = cp_val(*cpp++)) {
- ASSERT(is_CP((Eterm) cp));
- if (*cp_val((Eterm) cp) == i_return_trace) {
+ if (*cp == i_return_trace) {
/* Skip stack frame variables */
while (is_not_CP(*cpp)) cpp++;
cpp += 2; /* Skip return_trace parameters */
- } else if (*cp_val((Eterm) cp) == i_return_to_trace) {
+ } else if (*cp == i_return_to_trace) {
/* A return_to trace message is going to be generated
* by normal means, so we do not have to.
*/
@@ -2078,7 +2171,8 @@ erts_bif_trace(int bif_index, Process* p,
if (reason != TRAP) {
Eterm class;
Eterm value = p->fvalue;
- Eterm nocatch[3];
+ DeclareTmpHeapNoproc(nocatch,3);
+ UseTmpHeapNoproc(3);
/* Expand error value like in handle_error() */
if (reason & EXF_ARGLIST) {
Eterm *tp;
@@ -2126,6 +2220,7 @@ erts_bif_trace(int bif_index, Process* p,
}
}
}
+ UnUseTmpHeapNoproc(3);
if ((flags_meta|flags) & MATCH_SET_EXCEPTION_TRACE) {
erts_smp_proc_lock(p, ERTS_PROC_LOCKS_ALL_MINOR);
p->trace_flags |= F_EXCEPTION_TRACE;
@@ -2213,15 +2308,19 @@ trace_gc(Process *p, Eterm what)
BIN_OLD_VHEAP(p),
BIN_OLD_VHEAP_SZ(p)
};
- Eterm local_heap[(sizeof(values)/sizeof(Uint))
- *(2/*cons*/ + 3/*2-tuple*/ + BIG_UINT_HEAP_SIZE)
- + 5/*4-tuple */ + TS_HEAP_WORDS];
+#define LOCAL_HEAP_SIZE \
+ (sizeof(values)/sizeof(Eterm)) * \
+ (2/*cons*/ + 3/*2-tuple*/ + BIG_UINT_HEAP_SIZE) + \
+ 5/*4-tuple */ + TS_HEAP_WORDS
+ DeclareTmpHeap(local_heap,LOCAL_HEAP_SIZE,p);
#ifdef DEBUG
Eterm* limit;
#endif
ASSERT(sizeof(values)/sizeof(Uint) == sizeof(tags)/sizeof(Eterm));
+ UseTmpHeap(LOCAL_HEAP_SIZE,p);
+
if (is_internal_port(p->tracer_proc)) {
hp = local_heap;
#ifdef DEBUG
@@ -2252,7 +2351,7 @@ trace_gc(Process *p, Eterm what)
#ifdef DEBUG
limit = hp + size;
- ASSERT(size <= sizeof(local_heap)/sizeof(Eterm));
+ ASSERT(size <= LOCAL_HEAP_SIZE);
#endif
msg = erts_bld_atom_uint_2tup_list(&hp,
@@ -2275,6 +2374,8 @@ trace_gc(Process *p, Eterm what)
else
ERTS_ENQ_TRACE_MSG(p->id, tracer_ref, msg, bp);
erts_smp_mtx_unlock(&smq_mtx);
+ UnUseTmpHeap(LOCAL_HEAP_SIZE,p);
+#undef LOCAL_HEAP_SIZE
}
@@ -2465,7 +2566,9 @@ profile_scheduler(Eterm scheduler_id, Eterm state) {
Uint Ms, s, us;
#ifndef ERTS_SMP
- Eterm local_heap[4 + 7];
+#define LOCAL_HEAP_SIZE (4 + 7)
+ DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
+ UseTmpHeapNoproc(LOCAL_HEAP_SIZE);
hp = local_heap;
#else
ErlHeapFragment *bp;
@@ -2498,6 +2601,8 @@ profile_scheduler(Eterm scheduler_id, Eterm state) {
#ifndef ERTS_SMP
profile_send(msg);
+ UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+#undef LOCAL_HEAP_SIZE
#else
enqueue_sys_msg_unlocked(SYS_MSG_TYPE_SYSPROF, NIL, NIL, msg, bp);
#endif
@@ -2510,7 +2615,10 @@ profile_scheduler_q(Eterm scheduler_id, Eterm state, Eterm no_schedulers, Uint M
Eterm *hp, msg, timestamp;
#ifndef ERTS_SMP
- Eterm local_heap[4 + 7];
+#define LOCAL_HEAP_SIZE (4 + 7)
+ DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
+ UseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+
hp = local_heap;
#else
ErlHeapFragment *bp;
@@ -2528,6 +2636,8 @@ profile_scheduler_q(Eterm scheduler_id, Eterm state, Eterm no_schedulers, Uint M
msg = TUPLE6(hp, am_profile, am_scheduler, scheduler_id, state, no_schedulers, timestamp); hp += 7;
#ifndef ERTS_SMP
profile_send(msg);
+ UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+#undef LOCAL_HEAP_SIZE
#else
enqueue_sys_msg_unlocked(SYS_MSG_TYPE_SYSPROF, NIL, NIL, msg, bp);
#endif
@@ -2558,7 +2668,10 @@ trace_port_open(Port *p, Eterm calling_pid, Eterm drv_name) {
Eterm* hp;
if (is_internal_port(p->tracer_proc)) {
- Eterm local_heap[5+6];
+#define LOCAL_HEAP_SIZE (5+6)
+ DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
+ UseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+
hp = local_heap;
mess = TUPLE5(hp, am_trace, calling_pid, am_open, p->id, drv_name);
@@ -2569,6 +2682,8 @@ trace_port_open(Port *p, Eterm calling_pid, Eterm drv_name) {
}
/* No fake schedule */
send_to_port(NULL, mess, &p->tracer_proc, &p->trace_flags);
+ UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+#undef LOCAL_HEAP_SIZE
erts_smp_mtx_unlock(&smq_mtx);
} else {
ErlHeapFragment *bp;
@@ -2613,7 +2728,10 @@ trace_port(Port *t_p, Eterm what, Eterm data) {
Eterm* hp;
if (is_internal_port(t_p->tracer_proc)) {
- Eterm local_heap[5+5];
+#define LOCAL_HEAP_SIZE (5+5)
+ DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
+ UseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+
hp = local_heap;
mess = TUPLE4(hp, am_trace, t_p->id, what, data);
hp += 5;
@@ -2623,6 +2741,8 @@ trace_port(Port *t_p, Eterm what, Eterm data) {
}
/* No fake schedule */
send_to_port(NULL, mess, &t_p->tracer_proc, &t_p->trace_flags);
+ UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+#undef LOCAL_HEAP_SIZE
erts_smp_mtx_unlock(&smq_mtx);
} else {
ErlHeapFragment *bp;
@@ -2674,7 +2794,10 @@ trace_sched_ports_where(Port *p, Eterm what, Eterm where) {
Eterm sched_id = am_undefined;
if (is_internal_port(p->tracer_proc)) {
- Eterm local_heap[5+6];
+#define LOCAL_HEAP_SIZE (5+6)
+ DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
+ UseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+
hp = local_heap;
if (IS_TRACED_FL(p, F_TRACE_SCHED_NO)) {
@@ -2700,6 +2823,8 @@ trace_sched_ports_where(Port *p, Eterm what, Eterm where) {
/* No fake scheduling */
send_to_port(NULL, mess, &p->tracer_proc, &p->trace_flags);
+ UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+#undef LOCAL_HEAP_SIZE
erts_smp_mtx_unlock(&smq_mtx);
} else {
ErlHeapFragment *bp;
@@ -2750,7 +2875,11 @@ profile_runnable_port(Port *p, Eterm status) {
Eterm count = make_small(0);
#ifndef ERTS_SMP
- Eterm local_heap[4 + 6];
+#define LOCAL_HEAP_SIZE (4 + 6)
+
+ DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
+ UseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+
hp = local_heap;
#else
@@ -2771,6 +2900,8 @@ profile_runnable_port(Port *p, Eterm status) {
#ifndef ERTS_SMP
profile_send(msg);
+ UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+#undef LOCAL_HEAP_SIZE
#else
enqueue_sys_msg_unlocked(SYS_MSG_TYPE_SYSPROF, NIL, NIL, msg, bp);
#endif
@@ -2785,7 +2916,11 @@ profile_runnable_proc(Process *p, Eterm status){
Eterm where = am_undefined;
#ifndef ERTS_SMP
- Eterm local_heap[4 + 6 + 4];
+#define LOCAL_HEAP_SIZE (4 + 6 + 4)
+
+ DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
+ UseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+
hp = local_heap;
#else
ErlHeapFragment *bp;
@@ -2818,6 +2953,8 @@ profile_runnable_proc(Process *p, Eterm status){
msg = TUPLE5(hp, am_profile, p->id, status, where, timestamp); hp += 6;
#ifndef ERTS_SMP
profile_send(msg);
+ UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+#undef LOCAL_HEAP_SIZE
#else
enqueue_sys_msg_unlocked(SYS_MSG_TYPE_SYSPROF, NIL, NIL, msg, bp);
#endif
diff --git a/erts/emulator/beam/erl_unicode.c b/erts/emulator/beam/erl_unicode.c
index ab5811c70f..d01a3661f9 100644
--- a/erts/emulator/beam/erl_unicode.c
+++ b/erts/emulator/beam/erl_unicode.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2008-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2008-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -90,9 +90,9 @@ void erts_init_unicode(void)
am_atom_put("characters_to_utf8_trap",23);
characters_to_utf8_trap_exp.code[2] = 3;
characters_to_utf8_trap_exp.code[3] =
- (Eterm) em_apply_bif;
+ (BeamInstr) em_apply_bif;
characters_to_utf8_trap_exp.code[4] =
- (Eterm) &characters_to_utf8_trap;
+ (BeamInstr) &characters_to_utf8_trap;
memset(&characters_to_list_trap_1_exp, 0, sizeof(Export));
characters_to_list_trap_1_exp.address =
@@ -102,9 +102,9 @@ void erts_init_unicode(void)
am_atom_put("characters_to_list_trap_1",25);
characters_to_list_trap_1_exp.code[2] = 3;
characters_to_list_trap_1_exp.code[3] =
- (Eterm) em_apply_bif;
+ (BeamInstr) em_apply_bif;
characters_to_list_trap_1_exp.code[4] =
- (Eterm) &characters_to_list_trap_1;
+ (BeamInstr) &characters_to_list_trap_1;
memset(&characters_to_list_trap_2_exp, 0, sizeof(Export));
characters_to_list_trap_2_exp.address =
@@ -114,9 +114,9 @@ void erts_init_unicode(void)
am_atom_put("characters_to_list_trap_2",25);
characters_to_list_trap_2_exp.code[2] = 3;
characters_to_list_trap_2_exp.code[3] =
- (Eterm) em_apply_bif;
+ (BeamInstr) em_apply_bif;
characters_to_list_trap_2_exp.code[4] =
- (Eterm) &characters_to_list_trap_2;
+ (BeamInstr) &characters_to_list_trap_2;
memset(&characters_to_list_trap_3_exp, 0, sizeof(Export));
@@ -127,9 +127,9 @@ void erts_init_unicode(void)
am_atom_put("characters_to_list_trap_3",25);
characters_to_list_trap_3_exp.code[2] = 3;
characters_to_list_trap_3_exp.code[3] =
- (Eterm) em_apply_bif;
+ (BeamInstr) em_apply_bif;
characters_to_list_trap_3_exp.code[4] =
- (Eterm) &characters_to_list_trap_3;
+ (BeamInstr) &characters_to_list_trap_3;
memset(&characters_to_list_trap_4_exp, 0, sizeof(Export));
characters_to_list_trap_4_exp.address =
@@ -139,9 +139,9 @@ void erts_init_unicode(void)
am_atom_put("characters_to_list_trap_4",25);
characters_to_list_trap_4_exp.code[2] = 1;
characters_to_list_trap_4_exp.code[3] =
- (Eterm) em_apply_bif;
+ (BeamInstr) em_apply_bif;
characters_to_list_trap_4_exp.code[4] =
- (Eterm) &characters_to_list_trap_4;
+ (BeamInstr) &characters_to_list_trap_4;
c_to_b_int_trap_exportp = erts_export_put(am_unicode,am_characters_to_binary_int,2);
c_to_l_int_trap_exportp = erts_export_put(am_unicode,am_characters_to_list_int,2);
diff --git a/erts/emulator/beam/erl_vm.h b/erts/emulator/beam/erl_vm.h
index 50b3e5b61c..235bd7931d 100644
--- a/erts/emulator/beam/erl_vm.h
+++ b/erts/emulator/beam/erl_vm.h
@@ -50,6 +50,15 @@
#define MAX_ARG 256 /* Max number of arguments allowed */
#define MAX_REG 1024 /* Max number of x(N) registers used */
+/* Scheduler stores data for temporary heaps if
+ !HEAP_ON_C_STACK. Macros (*TmpHeap*) in global.h selects if we put temporary
+ heap data on the C stack or if we use the buffers in the scheduler data. */
+#define TMP_HEAP_SIZE 128 /* Number of Eterm in the schedulers
+ small heap for transient heap data */
+#define CMP_TMP_HEAP_SIZE 2 /* cmp wants its own tmp-heap... */
+#define ERL_ARITH_TMP_HEAP_SIZE 4 /* as does erl_arith... */
+#define BEAM_EMU_TMP_HEAP_SIZE 2 /* and beam_emu... */
+
/*
* The new arithmetic operations need some extra X registers in the register array.
*/
@@ -130,8 +139,12 @@
#define HeapWordsLeft(p) (HEAP_LIMIT(p) - HEAP_TOP(p))
#if defined(DEBUG) || defined(CHECK_FOR_HOLES)
+#if HALFWORD_HEAP
+# define ERTS_HOLE_MARKER (0xaf5e78ccU)
+#else
# define ERTS_HOLE_MARKER (((0xaf5e78ccUL << 24) << 8) | 0xaf5e78ccUL)
#endif
+#endif
/*
* Allocate heap memory on the ordinary heap, NEVER in a heap
diff --git a/erts/emulator/beam/error.h b/erts/emulator/beam/error.h
index 4930def4ed..ddc2c1396d 100644
--- a/erts/emulator/beam/error.h
+++ b/erts/emulator/beam/error.h
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1996-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1996-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -187,10 +187,10 @@ extern Eterm exception_tag[NUMBER_EXC_TAGS];
struct StackTrace {
Eterm header; /* bignum header - must be first in struct */
Eterm freason; /* original exception reason is saved in the struct */
- Eterm* pc;
- Eterm* current;
+ BeamInstr* pc;
+ BeamInstr* current;
int depth; /* number of saved pointers in trace[] */
- Eterm *trace[1]; /* varying size - must be last in struct */
+ BeamInstr *trace[1]; /* varying size - must be last in struct */
};
#endif /* __ERROR_H__ */
diff --git a/erts/emulator/beam/export.c b/erts/emulator/beam/export.c
index 271b40cf0f..66b05c0e9d 100644
--- a/erts/emulator/beam/export.c
+++ b/erts/emulator/beam/export.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1996-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1996-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -46,8 +46,8 @@ static erts_smp_rwmtx_t export_table_lock; /* Locks the secondary export table.
#define export_init_lock() erts_smp_rwmtx_init(&export_table_lock, \
"export_tab")
-extern Eterm* em_call_error_handler;
-extern Uint* em_call_traced_function;
+extern BeamInstr* em_call_error_handler;
+extern BeamInstr* em_call_traced_function;
void
export_info(int to, void *to_arg)
@@ -93,7 +93,7 @@ export_alloc(Export* tmpl)
obj->code[2] = tmpl->code[2];
obj->slot.index = -1;
obj->address = obj->code+3;
- obj->code[3] = (Eterm) em_call_error_handler;
+ obj->code[3] = (BeamInstr) em_call_error_handler;
obj->code[4] = 0;
obj->match_prog_set = NULL;
return obj;
@@ -140,7 +140,7 @@ init_export_table(void)
Export*
erts_find_export_entry(Eterm m, Eterm f, unsigned int a)
{
- HashValue hval = EXPORT_HASH(m, f, a);
+ HashValue hval = EXPORT_HASH((BeamInstr) m, (BeamInstr) f, (BeamInstr) a);
int ix;
HashBucket* b;
@@ -185,7 +185,7 @@ erts_find_function(Eterm m, Eterm f, unsigned int a)
ep = hash_get(&export_table.htable, (void*) &e);
if (ep != NULL && ep->address == ep->code+3 &&
- ep->code[3] != (Uint) em_call_traced_function) {
+ ep->code[3] != (BeamInstr) em_call_traced_function) {
ep = NULL;
}
return ep;
diff --git a/erts/emulator/beam/export.h b/erts/emulator/beam/export.h
index cd6af6dd85..87c1d483f4 100644
--- a/erts/emulator/beam/export.h
+++ b/erts/emulator/beam/export.h
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1996-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1996-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -52,7 +52,11 @@ typedef struct export
* on_load function that has not been run yet.
* Otherwise: 0.
*/
+#if HALFWORD_HEAP
+ BeamInstr code[5];
+#else
Eterm code[5];
+#endif
} Export;
@@ -74,6 +78,6 @@ Export *export_get(Export*);
#include "beam_load.h" /* For em_* extern declarations */
#define ExportIsBuiltIn(EntryPtr) \
(((EntryPtr)->address == (EntryPtr)->code + 3) && \
- ((EntryPtr)->code[3] == (Uint) em_apply_bif))
+ ((EntryPtr)->code[3] == (BeamInstr) em_apply_bif))
#endif
diff --git a/erts/emulator/beam/external.c b/erts/emulator/beam/external.c
index 099eddd195..f41b61d73d 100644
--- a/erts/emulator/beam/external.c
+++ b/erts/emulator/beam/external.c
@@ -1489,20 +1489,28 @@ dec_pid(ErtsDistExternal *edep, Eterm** hpp, byte* ep, ErlOffHeap* off_heap, Ete
static byte*
enc_term(ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, Uint32 dflags)
{
- DECLARE_ESTACK(s);
+ DECLARE_WSTACK(s);
Uint n;
Uint i;
Uint j;
Uint* ptr;
Eterm val;
FloatDef f;
+#if HALFWORD_HEAP
+ UWord wobj;
+#endif
+
goto L_jump_start;
outer_loop:
- while (!ESTACK_ISEMPTY(s)) {
- obj = ESTACK_POP(s);
- switch (val = ESTACK_POP(s)) {
+ while (!WSTACK_ISEMPTY(s)) {
+#if HALFWORD_HEAP
+ obj = (Eterm) (wobj = WSTACK_POP(s));
+#else
+ obj = WSTACK_POP(s);
+#endif
+ switch (val = WSTACK_POP(s)) {
case ENC_TERM:
break;
case ENC_ONE_CONS:
@@ -1513,29 +1521,40 @@ enc_term(ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, Uint32 dflags)
obj = CAR(cons);
tl = CDR(cons);
- ESTACK_PUSH(s, is_list(tl) ? ENC_ONE_CONS : ENC_TERM);
- ESTACK_PUSH(s, tl);
+ WSTACK_PUSH(s, is_list(tl) ? ENC_ONE_CONS : ENC_TERM);
+ WSTACK_PUSH(s, tl);
}
break;
case ENC_PATCH_FUN_SIZE:
{
+#if HALFWORD_HEAP
+ byte* size_p = (byte *) wobj;
+#else
byte* size_p = (byte *) obj;
-
+#endif
put_int32(ep - size_p, size_p);
}
goto outer_loop;
case ENC_LAST_ARRAY_ELEMENT:
{
+#if HALFWORD_HEAP
+ Eterm* ptr = (Eterm *) wobj;
+#else
Eterm* ptr = (Eterm *) obj;
+#endif
obj = *ptr;
}
break;
default: /* ENC_LAST_ARRAY_ELEMENT+1 and upwards */
{
+#if HALFWORD_HEAP
+ Eterm* ptr = (Eterm *) wobj;
+#else
Eterm* ptr = (Eterm *) obj;
+#endif
obj = *ptr++;
- ESTACK_PUSH(s, val-1);
- ESTACK_PUSH(s, (Eterm) ptr);
+ WSTACK_PUSH(s, val-1);
+ WSTACK_PUSH(s, (UWord) ptr);
}
break;
}
@@ -1563,8 +1582,10 @@ enc_term(ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, Uint32 dflags)
put_int32(val, ep);
ep += 4;
} else {
- Eterm tmp_big[2];
- Eterm big = small_to_big(val, tmp_big);
+ DeclareTmpHeapNoproc(tmp_big,2);
+ Eterm big;
+ UseTmpHeapNoproc(2);
+ big = small_to_big(val, tmp_big);
*ep++ = SMALL_BIG_EXT;
n = big_bytes(big);
ASSERT(n < 256);
@@ -1572,6 +1593,7 @@ enc_term(ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, Uint32 dflags)
ep += 1;
*ep++ = big_sign(big);
ep = big_to_bytes(big, ep);
+ UnUseTmpHeapNoproc(2);
}
}
break;
@@ -1662,8 +1684,8 @@ enc_term(ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, Uint32 dflags)
ep += 4;
}
if (i > 0) {
- ESTACK_PUSH(s, ENC_LAST_ARRAY_ELEMENT+i-1);
- ESTACK_PUSH(s, (Eterm) ptr);
+ WSTACK_PUSH(s, ENC_LAST_ARRAY_ELEMENT+i-1);
+ WSTACK_PUSH(s, (UWord) ptr);
}
break;
@@ -1741,7 +1763,7 @@ enc_term(ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, Uint32 dflags)
}
case EXPORT_DEF:
{
- Export* exp = (Export *) (export_val(obj))[1];
+ Export* exp = *((Export **) (export_val(obj) + 1));
if ((dflags & DFLAG_EXPORT_PTR_TAG) != 0) {
*ep++ = EXPORT_EXT;
ep = enc_atom(acmp, exp->code[0], ep, dflags);
@@ -1770,8 +1792,8 @@ enc_term(ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, Uint32 dflags)
int ei;
*ep++ = NEW_FUN_EXT;
- ESTACK_PUSH(s, ENC_PATCH_FUN_SIZE);
- ESTACK_PUSH(s, (Eterm) ep); /* Position for patching in size */
+ WSTACK_PUSH(s, ENC_PATCH_FUN_SIZE);
+ WSTACK_PUSH(s, (UWord) ep); /* Position for patching in size */
ep += 4;
*ep = funp->arity;
ep += 1;
@@ -1788,8 +1810,8 @@ enc_term(ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, Uint32 dflags)
fun_env:
for (ei = funp->num_free-1; ei > 0; ei--) {
- ESTACK_PUSH(s, ENC_TERM);
- ESTACK_PUSH(s, funp->env[ei]);
+ WSTACK_PUSH(s, ENC_TERM);
+ WSTACK_PUSH(s, (UWord) funp->env[ei]);
}
if (funp->num_free != 0) {
obj = funp->env[0];
@@ -1832,7 +1854,7 @@ enc_term(ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, Uint32 dflags)
break;
}
}
- DESTROY_ESTACK(s);
+ DESTROY_WSTACK(s);
return ep;
}
@@ -1952,11 +1974,11 @@ dec_term(ErtsDistExternal *edep, Eterm** hpp, byte* ep, ErlOffHeap* off_heap, Et
register Eterm* hp = *hpp; /* Please don't take the address of hp */
Eterm* next = objp;
- *next = (Eterm) NULL;
+ *next = (Eterm) (UWord) NULL;
while (next != NULL) {
objp = next;
- next = (Eterm *) (*objp);
+ next = (Eterm *) EXPAND_POINTER(*objp);
switch (*ep++) {
case INTEGER_EXT:
@@ -1964,7 +1986,7 @@ dec_term(ErtsDistExternal *edep, Eterm** hpp, byte* ep, ErlOffHeap* off_heap, Et
Sint sn = get_int32(ep);
ep += 4;
-#if defined(ARCH_64)
+#if defined(ARCH_64) && !HALFWORD_HEAP
*objp = make_small(sn);
#else
if (MY_IS_SSMALL(sn)) {
@@ -2061,7 +2083,7 @@ dec_term_atom_common:
hp += n;
objp = hp - 1;
while (n-- > 0) {
- objp[0] = (Eterm) next;
+ objp[0] = (Eterm) COMPRESS_POINTER(next);
next = objp;
objp--;
}
@@ -2079,12 +2101,12 @@ dec_term_atom_common:
*objp = make_list(hp);
hp += 2*n;
objp = hp - 2;
- objp[0] = (Eterm) (objp+1);
- objp[1] = (Eterm) next;
+ objp[0] = (Eterm) COMPRESS_POINTER((objp+1));
+ objp[1] = (Eterm) COMPRESS_POINTER(next);
next = objp;
objp -= 2;
while (--n > 0) {
- objp[0] = (Eterm) next;
+ objp[0] = (Eterm) COMPRESS_POINTER(next);
objp[1] = make_list(objp + 2);
next = objp;
objp -= 2;
@@ -2238,19 +2260,26 @@ dec_term_atom_common:
node = erts_find_or_insert_node(sysname, cre);
if(node == erts_this_node) {
RefThing *rtp = (RefThing *) hp;
- hp += REF_THING_HEAD_SIZE;
-#ifdef ARCH_64
+ ref_num = (Uint32 *) (hp + REF_THING_HEAD_SIZE);
+
+#if defined(ARCH_64) && !HALFWORD_HEAP
+ hp += REF_THING_HEAD_SIZE + ref_words/2 + 1;
rtp->header = make_ref_thing_header(ref_words/2 + 1);
#else
+ hp += REF_THING_HEAD_SIZE + ref_words;
rtp->header = make_ref_thing_header(ref_words);
#endif
*objp = make_internal_ref(rtp);
}
else {
ExternalThing *etp = (ExternalThing *) hp;
- hp += EXTERNAL_THING_HEAD_SIZE;
-
-#ifdef ARCH_64
+#if defined(ARCH_64) && !HALFWORD_HEAP
+ hp += EXTERNAL_THING_HEAD_SIZE + ref_words/2 + 1;
+#else
+ hp += EXTERNAL_THING_HEAD_SIZE + ref_words;
+#endif
+
+#if defined(ARCH_64) && !HALFWORD_HEAP
etp->header = make_external_ref_header(ref_words/2 + 1);
#else
etp->header = make_external_ref_header(ref_words);
@@ -2260,10 +2289,10 @@ dec_term_atom_common:
off_heap->externals = etp;
*objp = make_external_ref(etp);
+ ref_num = &(etp->data.ui32[0]);
}
- ref_num = (Uint32 *) hp;
-#ifdef ARCH_64
+#if defined(ARCH_64) && !HALFWORD_HEAP
*(ref_num++) = ref_words /* 32-bit arity */;
#endif
ref_num[0] = r0;
@@ -2271,12 +2300,9 @@ dec_term_atom_common:
ref_num[i] = get_int32(ep);
ep += 4;
}
-#ifdef ARCH_64
+#if defined(ARCH_64) && !HALFWORD_HEAP
if ((1 + ref_words) % 2)
ref_num[ref_words] = 0;
- hp += ref_words/2 + 1;
-#else
- hp += ref_words;
#endif
break;
}
@@ -2398,7 +2424,12 @@ dec_term_atom_common:
}
*objp = make_export(hp);
*hp++ = HEADER_EXPORT;
+#if HALFWORD_HEAP
+ *((UWord *) (UWord) hp) = (UWord) erts_export_get_or_make_stub(mod, name, arity);
+ hp += 2;
+#else
*hp++ = (Eterm) erts_export_get_or_make_stub(mod, name, arity);
+#endif
break;
}
break;
@@ -2474,11 +2505,11 @@ dec_term_atom_common:
/* Environment */
for (i = num_free-1; i >= 0; i--) {
- funp->env[i] = (Eterm) next;
+ funp->env[i] = (Eterm) COMPRESS_POINTER(next);
next = funp->env + i;
}
/* Creator */
- funp->creator = (Eterm) next;
+ funp->creator = (Eterm) COMPRESS_POINTER(next);
next = &(funp->creator);
break;
}
@@ -2549,7 +2580,7 @@ dec_term_atom_common:
/* Environment */
for (i = num_free-1; i >= 0; i--) {
- funp->env[i] = (Eterm) next;
+ funp->env[i] = (Eterm) COMPRESS_POINTER(next);
next = funp->env + i;
}
break;
@@ -2580,26 +2611,35 @@ dec_term_atom_common:
static Uint
encode_size_struct2(ErtsAtomCacheMap *acmp, Eterm obj, unsigned dflags)
{
- DECLARE_ESTACK(s);
+ DECLARE_WSTACK(s);
Uint m, i, arity;
Uint result = 0;
+#if HALFWORD_HEAP
+ UWord wobj = 0;
+#endif
goto L_jump_start;
outer_loop:
- while (!ESTACK_ISEMPTY(s)) {
- obj = ESTACK_POP(s);
-
+ while (!WSTACK_ISEMPTY(s)) {
+#if HALFWORD_HEAP
+ obj = (Eterm) (wobj = WSTACK_POP(s));
+#else
+ obj = WSTACK_POP(s);
+#endif
handle_popped_obj:
- if (is_CP(obj)) {
+ if (is_CP(obj)) { /* Does not look for CP, looks for "no tag" */
+#if HALFWORD_HEAP
+ Eterm* ptr = (Eterm *) wobj;
+#else
Eterm* ptr = (Eterm *) obj;
-
+#endif
/*
* Pointer into a tuple.
*/
obj = *ptr--;
if (!is_header(obj)) {
- ESTACK_PUSH(s, (Eterm)ptr);
+ WSTACK_PUSH(s, (UWord)ptr);
} else {
/* Reached tuple header */
ASSERT(header_is_arityval(obj));
@@ -2611,7 +2651,7 @@ encode_size_struct2(ErtsAtomCacheMap *acmp, Eterm obj, unsigned dflags)
tl = CDR(cons);
obj = CAR(cons);
- ESTACK_PUSH(s, tl);
+ WSTACK_PUSH(s, tl);
} else if (is_nil(obj)) {
result++;
goto outer_loop;
@@ -2650,9 +2690,11 @@ encode_size_struct2(ErtsAtomCacheMap *acmp, Eterm obj, unsigned dflags)
else if (sizeof(Sint) == 4 || IS_SSMALL28(val))
result += 1 + 4; /* INTEGER_EXT */
else {
- Eterm tmp_big[2];
+ DeclareTmpHeapNoproc(tmp_big,2);
+ UseTmpHeapNoproc(2);
i = big_bytes(small_to_big(val, tmp_big));
result += 1 + 1 + 1 + i; /* SMALL_BIG_EXT */
+ UnUseTmpHeapNoproc(2);
}
}
break;
@@ -2698,7 +2740,11 @@ encode_size_struct2(ErtsAtomCacheMap *acmp, Eterm obj, unsigned dflags)
result += 1 + 4;
}
ptr += arity;
+#if HALFWORD_HEAP
+ obj = (Eterm) (wobj = (UWord) ptr);
+#else
obj = (Eterm) ptr;
+#endif
goto handle_popped_obj;
}
break;
@@ -2740,14 +2786,14 @@ encode_size_struct2(ErtsAtomCacheMap *acmp, Eterm obj, unsigned dflags)
if (is_not_list(obj)) {
/* Push any non-list terms on the stack */
- ESTACK_PUSH(s, obj);
+ WSTACK_PUSH(s, obj);
} else {
/* Lists must be handled specially. */
if ((m = is_string(obj)) && (m < MAX_STRING_LEN)) {
result += m + 2 + 1;
} else {
result += 5;
- ESTACK_PUSH(s, obj);
+ WSTACK_PUSH(s, obj);
}
}
}
@@ -2760,8 +2806,12 @@ encode_size_struct2(ErtsAtomCacheMap *acmp, Eterm obj, unsigned dflags)
case EXPORT_DEF:
{
- Export* ep = (Export *) (export_val(obj))[1];
+ Export* ep = *((Export **) (export_val(obj) + 1));
+#if HALFWORD_HEAP
+ result += 2;
+#else
result += 1;
+#endif
result += encode_size_struct2(acmp, ep->code[0], dflags);
result += encode_size_struct2(acmp, ep->code[1], dflags);
result += encode_size_struct2(acmp, make_small(ep->code[2]), dflags);
@@ -2774,7 +2824,7 @@ encode_size_struct2(ErtsAtomCacheMap *acmp, Eterm obj, unsigned dflags)
}
}
- DESTROY_ESTACK(s);
+ DESTROY_WSTACK(s);
return result;
}
@@ -2886,7 +2936,7 @@ decoded_size(byte *ep, byte* endp, int no_refc_bins)
ep += 2;
atom_extra_skip = 1 + 4*id_words;
/* In case it is an external ref */
-#ifdef ARCH_64
+#if defined(ARCH_64) && !HALFWORD_HEAP
heap_size += EXTERNAL_THING_HEAD_SIZE + id_words/2 + 1;
#else
heap_size += EXTERNAL_THING_HEAD_SIZE + id_words;
@@ -2961,7 +3011,11 @@ decoded_size(byte *ep, byte* endp, int no_refc_bins)
break;
case EXPORT_EXT:
terms += 3;
+#if HALFWORD_HEAP
+ heap_size += 3;
+#else
heap_size += 2;
+#endif
break;
case NEW_FUN_EXT:
{
diff --git a/erts/emulator/beam/external.h b/erts/emulator/beam/external.h
index eada6d4f27..db86b4d796 100644
--- a/erts/emulator/beam/external.h
+++ b/erts/emulator/beam/external.h
@@ -212,7 +212,7 @@ erts_dist_ext_trailer(ErtsDistExternal *edep)
{
void *res = (void *) (edep->ext_endp
+ ERTS_WORD_ALIGN_PAD_SZ(edep->ext_endp));
- ASSERT((((Uint) res) % sizeof(Uint)) == 0);
+ ASSERT((((UWord) res) % sizeof(Uint)) == 0);
return res;
}
diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h
index cab249a53f..cefdf80fb4 100644
--- a/erts/emulator/beam/global.h
+++ b/erts/emulator/beam/global.h
@@ -403,7 +403,7 @@ extern Eterm erts_ddll_monitor_driver(Process *p,
/* Add fields in ERTS_INTERNAL_BINARY_FIELDS, otherwise the drivers crash */
#define ERTS_INTERNAL_BINARY_FIELDS \
- Uint flags; \
+ UWord flags; \
erts_refc_t refc; \
ERTS_BINARY_STRUCT_ALIGNMENT
@@ -723,6 +723,60 @@ do { \
#define ESTACK_POP(s) (*(--ESTK_CONCAT(s,_sp)))
+void erl_grow_wstack(UWord** start, UWord** sp, UWord** end);
+#define WSTK_CONCAT(a,b) a##b
+#define WSTK_SUBSCRIPT(s,i) *((UWord *)((byte *)WSTK_CONCAT(s,_start) + (i)))
+#define DEF_WSTACK_SIZE (16)
+
+#define DECLARE_WSTACK(s) \
+ UWord WSTK_CONCAT(s,_default_stack)[DEF_WSTACK_SIZE]; \
+ UWord* WSTK_CONCAT(s,_start) = WSTK_CONCAT(s,_default_stack); \
+ UWord* WSTK_CONCAT(s,_sp) = WSTK_CONCAT(s,_start); \
+ UWord* WSTK_CONCAT(s,_end) = WSTK_CONCAT(s,_start) + DEF_WSTACK_SIZE
+
+#define DESTROY_WSTACK(s) \
+do { \
+ if (WSTK_CONCAT(s,_start) != WSTK_CONCAT(s,_default_stack)) { \
+ erts_free(ERTS_ALC_T_ESTACK, WSTK_CONCAT(s,_start)); \
+ } \
+} while(0)
+
+#define WSTACK_PUSH(s, x) \
+do { \
+ if (WSTK_CONCAT(s,_sp) == WSTK_CONCAT(s,_end)) { \
+ erl_grow_wstack(&WSTK_CONCAT(s,_start), &WSTK_CONCAT(s,_sp), \
+ &WSTK_CONCAT(s,_end)); \
+ } \
+ *WSTK_CONCAT(s,_sp)++ = (x); \
+} while(0)
+
+#define WSTACK_PUSH2(s, x, y) \
+do { \
+ if (WSTK_CONCAT(s,_sp) > WSTK_CONCAT(s,_end) - 2) { \
+ erl_grow_wstack(&WSTK_CONCAT(s,_start), &WSTK_CONCAT(s,_sp), \
+ &WSTK_CONCAT(s,_end)); \
+ } \
+ *WSTK_CONCAT(s,_sp)++ = (x); \
+ *WSTK_CONCAT(s,_sp)++ = (y); \
+} while(0)
+
+#define WSTACK_PUSH3(s, x, y, z) \
+do { \
+ if (WSTK_CONCAT(s,_sp) > WSTK_CONCAT(s,_end) - 3) { \
+ erl_grow_wstack(&WSTK_CONCAT(s,_start), &WSTK_CONCAT(s,_sp), \
+ &WSTK_CONCAT(s,_end)); \
+ } \
+ *WSTK_CONCAT(s,_sp)++ = (x); \
+ *WSTK_CONCAT(s,_sp)++ = (y); \
+ *WSTK_CONCAT(s,_sp)++ = (z); \
+} while(0)
+
+#define WSTACK_COUNT(s) (WSTK_CONCAT(s,_sp) - WSTK_CONCAT(s,_start))
+
+#define WSTACK_ISEMPTY(s) (WSTK_CONCAT(s,_sp) == WSTK_CONCAT(s,_start))
+#define WSTACK_POP(s) (*(--WSTK_CONCAT(s,_sp)))
+
+
/* port status flags */
#define ERTS_PORT_SFLG_CONNECTED ((Uint32) (1 << 0))
@@ -802,7 +856,7 @@ void erts_system_profile_clear(Process *c_p);
int erts_load_module(Process *c_p, ErtsProcLocks c_p_locks,
Eterm group_leader, Eterm* mod, byte* code, int size);
void init_load(void);
-Eterm* find_function_from_pc(Eterm* pc);
+BeamInstr* find_function_from_pc(BeamInstr* pc);
Eterm erts_module_info_0(Process* p, Eterm module);
Eterm erts_module_info_1(Process* p, Eterm module, Eterm what);
Eterm erts_make_stub_module(Process* p, Eterm Mod, Eterm Beam, Eterm Info);
@@ -1171,7 +1225,7 @@ erts_smp_port_unlock(Port *prt)
ERTS_INVALID_PORT_OPT((PP), (ID), ERTS_PORT_SFLGS_INVALID_TRACER_LOOKUP)
#define ERTS_PORT_SCHED_ID(P, ID) \
- ((Uint) erts_prtsd_set((P), ERTS_PSD_SCHED_ID, (void *) (ID)))
+ ((Uint) (UWord) erts_prtsd_set((P), ERTS_PSD_SCHED_ID, (void *) (UWord) (ID)))
#ifdef ERTS_SMP
Port *erts_de2port(DistEntry *, Process *, ErtsProcLocks);
@@ -1463,6 +1517,7 @@ Uint32 make_hash(Eterm);
Eterm erts_bld_atom(Uint **hpp, Uint *szp, char *str);
Eterm erts_bld_uint(Uint **hpp, Uint *szp, Uint ui);
+Eterm erts_bld_uword(Uint **hpp, Uint *szp, UWord uw);
Eterm erts_bld_uint64(Uint **hpp, Uint *szp, Uint64 ui64);
Eterm erts_bld_sint64(Uint **hpp, Uint *szp, Sint64 si64);
Eterm erts_bld_cons(Uint **hpp, Uint *szp, Eterm car, Eterm cdr);
@@ -1515,7 +1570,9 @@ Sint cmp(Eterm, Eterm);
#define CMP_EQ(a,b) ((a) == (b) || cmp_eq((a),(b)))
#define CMP_NE(a,b) ((a) != (b) && cmp_ne((a),(b)))
+/* duplicates from big.h */
int term_to_Uint(Eterm term, Uint *up);
+int term_to_UWord(Eterm, UWord*);
#ifdef HAVE_ERTS_NOW_CPU
extern int erts_cpu_timestamp;
@@ -1554,12 +1611,12 @@ void erts_queue_error_logger_message(Eterm, Eterm, ErlHeapFragment *);
void erts_send_sys_msg_proc(Eterm, Eterm, Eterm, ErlHeapFragment *);
void trace_send(Process*, Eterm, Eterm);
void trace_receive(Process*, Eterm);
-Uint32 erts_call_trace(Process *p, Eterm mfa[], Binary *match_spec, Eterm* args,
+Uint32 erts_call_trace(Process *p, BeamInstr mfa[], Binary *match_spec, Eterm* args,
int local, Eterm *tracer_pid);
-void erts_trace_return(Process* p, Eterm* fi, Eterm retval, Eterm *tracer_pid);
-void erts_trace_exception(Process* p, Eterm mfa[], Eterm class, Eterm value,
+void erts_trace_return(Process* p, BeamInstr* fi, Eterm retval, Eterm *tracer_pid);
+void erts_trace_exception(Process* p, BeamInstr mfa[], Eterm class, Eterm value,
Eterm *tracer);
-void erts_trace_return_to(Process *p, Uint *pc);
+void erts_trace_return_to(Process *p, BeamInstr *pc);
void trace_sched(Process*, Eterm);
void trace_proc(Process*, Process*, Eterm, Eterm);
void trace_proc_spawn(Process*, Eterm pid, Eterm mod, Eterm func, Eterm args);
@@ -1589,7 +1646,7 @@ Uint erts_trace_flag2bit(Eterm flag);
int erts_trace_flags(Eterm List,
Uint *pMask, Eterm *pTracer, int *pCpuTimestamp);
Eterm erts_bif_trace(int bif_index, Process* p,
- Eterm arg1, Eterm arg2, Eterm arg3, Uint *I);
+ Eterm arg1, Eterm arg2, Eterm arg3, BeamInstr *I);
#ifdef ERTS_SMP
void erts_send_pending_trace_msgs(ErtsSchedulerData *esdp);
@@ -1606,7 +1663,7 @@ void bin_write(int, void*, byte*, int);
int intlist_to_buf(Eterm, char*, int); /* most callers pass plain char*'s */
struct Sint_buf {
-#ifdef ARCH_64
+#if defined(ARCH_64) && !HALFWORD_HEAP
char s[22];
#else
char s[12];
@@ -1839,4 +1896,61 @@ erts_alloc_message_heap(Uint size,
#endif /* #if ERTS_GLB_INLINE_INCL_FUNC_DEF */
+#if !HEAP_ON_C_STACK
+# if defined(DEBUG)
+# define DeclareTmpHeap(VariableName,Size,Process) \
+ Eterm *VariableName = erts_debug_allocate_tmp_heap(Size,Process)
+# define DeclareTmpHeapNoproc(VariableName,Size) \
+ Eterm *VariableName = erts_debug_allocate_tmp_heap(Size,NULL)
+# define UseTmpHeap(Size,Proc) \
+ do { \
+ erts_debug_use_tmp_heap((Size),(Proc)); \
+ } while (0)
+# define UnUseTmpHeap(Size,Proc) \
+ do { \
+ erts_debug_unuse_tmp_heap((Size),(Proc)); \
+ } while (0)
+# define UseTmpHeapNoproc(Size) \
+ do { \
+ erts_debug_use_tmp_heap(Size,NULL); \
+ } while (0)
+# define UnUseTmpHeapNoproc(Size) \
+ do { \
+ erts_debug_unuse_tmp_heap(Size,NULL); \
+ } while (0)
+# else
+# define DeclareTmpHeap(VariableName,Size,Process) \
+ Eterm *VariableName = (ERTS_PROC_GET_SCHDATA(Process)->tmp_heap)+(ERTS_PROC_GET_SCHDATA(Process)->num_tmp_heap_used)
+# define DeclareTmpHeapNoproc(VariableName,Size) \
+ Eterm *VariableName = (erts_get_scheduler_data()->tmp_heap)+(erts_get_scheduler_data()->num_tmp_heap_used)
+# define UseTmpHeap(Size,Proc) \
+ do { \
+ ERTS_PROC_GET_SCHDATA(Proc)->num_tmp_heap_used += (Size); \
+ } while (0)
+# define UnUseTmpHeap(Size,Proc) \
+ do { \
+ ERTS_PROC_GET_SCHDATA(Proc)->num_tmp_heap_used -= (Size); \
+ } while (0)
+# define UseTmpHeapNoproc(Size) \
+ do { \
+ erts_get_scheduler_data()->num_tmp_heap_used += (Size); \
+ } while (0)
+# define UnUseTmpHeapNoproc(Size) \
+ do { \
+ erts_get_scheduler_data()->num_tmp_heap_used -= (Size); \
+ } while (0)
+
+
+# endif
+
+#else
+# define DeclareTmpHeap(VariableName,Size,Process) \
+ Eterm VariableName[Size]
+# define DeclareTmpHeapNoproc(VariableName,Size) \
+ Eterm VariableName[Size]
+# define UseTmpHeap(Size,Proc) /* Nothing */
+# define UnUseTmpHeap(Size,Proc) /* Nothing */
+# define UseTmpHeapNoproc(Size) /* Nothing */
+# define UnUseTmpHeapNoproc(Size) /* Nothing */
+#endif
#endif
diff --git a/erts/emulator/beam/io.c b/erts/emulator/beam/io.c
index 3309b77086..10f1082039 100644
--- a/erts/emulator/beam/io.c
+++ b/erts/emulator/beam/io.c
@@ -72,6 +72,15 @@ erts_driver_t fd_driver;
static int init_driver(erts_driver_t *, ErlDrvEntry *, DE_Handle *);
static void terminate_port(Port *p);
static void pdl_init(void);
+#ifdef ERTS_SMP
+static void driver_monitor_lock_pdl(Port *p);
+static void driver_monitor_unlock_pdl(Port *p);
+#define DRV_MONITOR_LOCK_PDL(Port) driver_monitor_lock_pdl(Port)
+#define DRV_MONITOR_UNLOCK_PDL(Port) driver_monitor_unlock_pdl(Port)
+#else
+#define DRV_MONITOR_LOCK_PDL(Port) /* nothing */
+#define DRV_MONITOR_UNLOCK_PDL(Port) /* nothing */
+#endif
static ERTS_INLINE ErlIOQueue*
drvport2ioq(ErlDrvPort drvport)
@@ -1998,12 +2007,13 @@ erts_do_exit_port(Port *p, Eterm from, Eterm reason)
p->nlinks = NULL;
erts_sweep_links(lnk, &sweep_one_link, &sc);
}
+ DRV_MONITOR_LOCK_PDL(p);
{
ErtsMonitor *moni = p->monitors;
p->monitors = NULL;
erts_sweep_monitors(moni, &sweep_one_monitor, NULL);
}
-
+ DRV_MONITOR_UNLOCK_PDL(p);
if ((p->status & ERTS_PORT_SFLG_DISTRIBUTION) && p->dist_entry) {
erts_do_net_exits(p->dist_entry, rreason);
@@ -3536,6 +3546,32 @@ static ERTS_INLINE void pdl_destroy(ErlDrvPDL pdl)
erts_free(ERTS_ALC_T_PORT_DATA_LOCK, pdl);
}
+#ifdef ERTS_SMP
+
+static void driver_monitor_lock_pdl(Port *p) {
+ if (p->port_data_lock) {
+ driver_pdl_lock(p->port_data_lock);
+ }
+ /* Now we either have the port lock or the port_data_lock */
+ ERTS_LC_ASSERT(!p->port_data_lock
+ || erts_lc_mtx_is_locked(&(p->port_data_lock->mtx)));
+ ERTS_SMP_LC_ASSERT(p->port_data_lock
+ || erts_lc_is_port_locked(p));
+}
+
+static void driver_monitor_unlock_pdl(Port *p) {
+ /* We should either have the port lock or the port_data_lock */
+ ERTS_LC_ASSERT(!p->port_data_lock
+ || erts_lc_mtx_is_locked(&(p->port_data_lock->mtx)));
+ ERTS_SMP_LC_ASSERT(p->port_data_lock
+ || erts_lc_is_port_locked(p));
+ if (p->port_data_lock) {
+ driver_pdl_unlock(p->port_data_lock);
+ }
+}
+
+#endif
+
/*
* exported driver_pdl_* functions ...
*/
@@ -3994,7 +4030,7 @@ drv_cancel_timer(Port *prt)
erts_port_task_abort(prt->id, &prt->timeout_task);
}
-int driver_set_timer(ErlDrvPort ix, Uint t)
+int driver_set_timer(ErlDrvPort ix, UWord t)
{
Port* prt = erts_drvport2port(ix);
@@ -4053,12 +4089,16 @@ driver_read_timer(ErlDrvPort ix, unsigned long* t)
int
driver_get_now(ErlDrvNowData *now_data)
{
+ Uint mega,secs,micro;
ERTS_SMP_CHK_NO_PROC_LOCKS;
if (now_data == NULL) {
return -1;
}
- get_now(&(now_data->megasecs),&(now_data->secs),&(now_data->microsecs));
+ get_now(&mega,&secs,&micro);
+ now_data->megasecs = (unsigned long) mega;
+ now_data->secs = (unsigned long) secs;
+ now_data->microsecs = (unsigned long) micro;
return 0;
}
@@ -4072,14 +4112,15 @@ static void ref_to_driver_monitor(Eterm ref, ErlDrvMonitor *mon)
memcpy(mon,refp,sizeof(RefThing));
}
-int driver_monitor_process(ErlDrvPort port,
- ErlDrvTermData process,
- ErlDrvMonitor *monitor)
+
+static int do_driver_monitor_process(Port *prt,
+ Eterm *buf,
+ ErlDrvTermData process,
+ ErlDrvMonitor *monitor)
{
- Port *prt = erts_drvport2port(port);
Process *rp;
Eterm ref;
- Eterm buf[REF_THING_SIZE];
+
if (prt->drv_ptr->process_exit == NULL) {
return -1;
}
@@ -4089,22 +4130,76 @@ int driver_monitor_process(ErlDrvPort port,
if (!rp) {
return 1;
}
+
ref = erts_make_ref_in_buffer(buf);
erts_add_monitor(&(prt->monitors), MON_ORIGIN, ref, rp->id, NIL);
erts_add_monitor(&(rp->monitors), MON_TARGET, ref, prt->id, NIL);
-
+
erts_smp_proc_unlock(rp, ERTS_PROC_LOCK_LINK);
ref_to_driver_monitor(ref,monitor);
return 0;
}
-int driver_demonitor_process(ErlDrvPort port,
- const ErlDrvMonitor *monitor)
+/*
+ * This can be called from a non scheduler thread iff a port_data_lock exists
+ */
+int driver_monitor_process(ErlDrvPort port,
+ ErlDrvTermData process,
+ ErlDrvMonitor *monitor)
+{
+ Port *prt;
+ int ret;
+ Uint32 status;
+ ErtsSchedulerData *sched = erts_get_scheduler_data();
+ int ix = (int) port;
+ if (ix < 0 || erts_max_ports <= ix) {
+ return -1;
+ }
+ prt = &erts_port[ix];
+
+ DRV_MONITOR_LOCK_PDL(prt);
+
+ if (sched) {
+ status = erts_port[ix].status;
+ } else {
+ erts_smp_port_state_lock(prt);
+ status = erts_port[ix].status;
+ erts_smp_port_state_unlock(prt);
+ }
+
+ if (status & ERTS_PORT_SFLGS_INVALID_DRIVER_LOOKUP) {
+ DRV_MONITOR_UNLOCK_PDL(prt);
+ return -1;
+ }
+
+ /* Now (in SMP) we should have either the port lock (if we have a scheduler) or the port data lock
+ (if we're a driver thread) */
+ ERTS_SMP_LC_ASSERT((sched != NULL || prt->port_data_lock));
+
+#if !HEAP_ON_C_STACK
+ if (!sched) {
+ /* Need a separate allocation for the ref :( */
+ Eterm *buf = erts_alloc(ERTS_ALC_T_TEMP_TERM,
+ sizeof(Eterm)*REF_THING_SIZE);
+ ret = do_driver_monitor_process(prt,buf,process,monitor);
+ erts_free(ERTS_ALC_T_TEMP_TERM,buf);
+ } else
+#endif
+ {
+ DeclareTmpHeapNoproc(buf,REF_THING_SIZE);
+ UseTmpHeapNoproc(REF_THING_SIZE);
+ ret = do_driver_monitor_process(prt,buf,process,monitor);
+ UnUseTmpHeapNoproc(REF_THING_SIZE);
+ }
+ DRV_MONITOR_UNLOCK_PDL(prt);
+ return ret;
+}
+
+static int do_driver_demonitor_process(Port *prt, Eterm *buf,
+ const ErlDrvMonitor *monitor)
{
- Port *prt = erts_drvport2port(port);
Process *rp;
Eterm ref;
- Eterm buf[REF_THING_SIZE];
ErtsMonitor *mon;
Eterm to;
@@ -4137,12 +4232,60 @@ int driver_demonitor_process(ErlDrvPort port,
return 0;
}
-ErlDrvTermData driver_get_monitored_process(ErlDrvPort port,
+int driver_demonitor_process(ErlDrvPort port,
+ const ErlDrvMonitor *monitor)
+{
+ Port *prt;
+ int ret;
+ Uint32 status;
+ ErtsSchedulerData *sched = erts_get_scheduler_data();
+ int ix = (int) port;
+ if (ix < 0 || erts_max_ports <= ix) {
+ return -1;
+ }
+ prt = &erts_port[ix];
+
+ DRV_MONITOR_LOCK_PDL(prt);
+
+ if (sched) {
+ status = erts_port[ix].status;
+ } else {
+ erts_smp_port_state_lock(prt);
+ status = erts_port[ix].status;
+ erts_smp_port_state_unlock(prt);
+ }
+
+ if (status & ERTS_PORT_SFLGS_INVALID_DRIVER_LOOKUP) {
+ DRV_MONITOR_UNLOCK_PDL(prt);
+ return -1;
+ }
+
+ /* Now we should have either the port lock (if we have a scheduler) or the port data lock
+ (if we're a driver thread) */
+ ERTS_SMP_LC_ASSERT((sched != NULL || prt->port_data_lock));
+#if !HEAP_ON_C_STACK
+ if (!sched) {
+ /* Need a separate allocation for the ref :( */
+ Eterm *buf = erts_alloc(ERTS_ALC_T_TEMP_TERM,
+ sizeof(Eterm)*REF_THING_SIZE);
+ ret = do_driver_demonitor_process(prt,buf,monitor);
+ erts_free(ERTS_ALC_T_TEMP_TERM,buf);
+ } else
+#endif
+ {
+ DeclareTmpHeapNoproc(buf,REF_THING_SIZE);
+ UseTmpHeapNoproc(REF_THING_SIZE);
+ ret = do_driver_demonitor_process(prt,buf,monitor);
+ UnUseTmpHeapNoproc(REF_THING_SIZE);
+ }
+ DRV_MONITOR_UNLOCK_PDL(prt);
+ return ret;
+}
+
+static ErlDrvTermData do_driver_get_monitored_process(Port *prt, Eterm *buf,
const ErlDrvMonitor *monitor)
{
- Port *prt = erts_drvport2port(port);
Eterm ref;
- Eterm buf[REF_THING_SIZE];
ErtsMonitor *mon;
Eterm to;
@@ -4158,6 +4301,59 @@ ErlDrvTermData driver_get_monitored_process(ErlDrvPort port,
return (ErlDrvTermData) to;
}
+
+ErlDrvTermData driver_get_monitored_process(ErlDrvPort port,
+ const ErlDrvMonitor *monitor)
+{
+ Port *prt;
+ ErlDrvTermData ret;
+ Uint32 status;
+ ErtsSchedulerData *sched = erts_get_scheduler_data();
+ int ix = (int) port;
+ if (ix < 0 || erts_max_ports <= ix) {
+ return driver_term_nil;
+ }
+ prt = &erts_port[ix];
+
+ DRV_MONITOR_LOCK_PDL(prt);
+
+ if (sched) {
+ status = erts_port[ix].status;
+ } else {
+ erts_smp_port_state_lock(prt);
+ status = erts_port[ix].status;
+ erts_smp_port_state_unlock(prt);
+ }
+
+ if (status & ERTS_PORT_SFLGS_INVALID_DRIVER_LOOKUP) {
+ DRV_MONITOR_UNLOCK_PDL(prt);
+ return driver_term_nil;
+ }
+
+ /* Now we should have either the port lock (if we have a scheduler) or the port data lock
+ (if we're a driver thread) */
+ ERTS_SMP_LC_ASSERT((sched != NULL || prt->port_data_lock));
+
+#if !HEAP_ON_C_STACK
+ if (!sched) {
+ /* Need a separate allocation for the ref :( */
+ Eterm *buf = erts_alloc(ERTS_ALC_T_TEMP_TERM,
+ sizeof(Eterm)*REF_THING_SIZE);
+ ret = do_driver_get_monitored_process(prt,buf,monitor);
+ erts_free(ERTS_ALC_T_TEMP_TERM,buf);
+ } else
+#endif
+ {
+ DeclareTmpHeapNoproc(buf,REF_THING_SIZE);
+ UseTmpHeapNoproc(REF_THING_SIZE);
+ ret = do_driver_get_monitored_process(prt,buf,monitor);
+ UnUseTmpHeapNoproc(REF_THING_SIZE);
+ }
+ DRV_MONITOR_UNLOCK_PDL(prt);
+ return ret;
+}
+
+
int driver_compare_monitors(const ErlDrvMonitor *monitor1,
const ErlDrvMonitor *monitor2)
{
@@ -4173,18 +4369,22 @@ void erts_fire_port_monitor(Port *prt, Eterm ref)
ERTS_SMP_LC_ASSERT(erts_lc_is_port_locked(prt));
ASSERT(prt->drv_ptr != NULL);
-
+ DRV_MONITOR_LOCK_PDL(prt);
if (erts_lookup_monitor(prt->monitors,ref) == NULL) {
+ DRV_MONITOR_UNLOCK_PDL(prt);
return;
}
callback = prt->drv_ptr->process_exit;
ASSERT(callback != NULL);
ref_to_driver_monitor(ref,&drv_monitor);
+ DRV_MONITOR_UNLOCK_PDL(prt);
fpe_was_unmasked = erts_block_fpe();
(*callback)((ErlDrvData) (prt->drv_data), &drv_monitor);
erts_unblock_fpe(fpe_was_unmasked);
+ DRV_MONITOR_LOCK_PDL(prt);
/* remove monitor *after* callback */
rmon = erts_remove_monitor(&(prt->monitors),ref);
+ DRV_MONITOR_UNLOCK_PDL(prt);
if (rmon) {
erts_destroy_monitor(rmon);
}
diff --git a/erts/emulator/beam/module.h b/erts/emulator/beam/module.h
index 87d13b3607..694e4ab72f 100644
--- a/erts/emulator/beam/module.h
+++ b/erts/emulator/beam/module.h
@@ -29,8 +29,8 @@ typedef struct erl_module {
IndexSlot slot; /* Must be located at top of struct! */
int module; /* Atom index for module (not tagged). */
- Eterm* code;
- Eterm* old_code;
+ BeamInstr* code;
+ BeamInstr* old_code;
int code_length; /* Length of loaded code in bytes. */
int old_code_length; /* Length of old loaded code in bytes */
unsigned catches, old_catches;
diff --git a/erts/emulator/beam/sys.h b/erts/emulator/beam/sys.h
index 4b949523fa..a86bcb80dd 100644
--- a/erts/emulator/beam/sys.h
+++ b/erts/emulator/beam/sys.h
@@ -1,25 +1,26 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1996-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1996-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
#ifndef __SYS_H__
#define __SYS_H__
+
#if defined(VALGRIND) && !defined(NO_FPE_SIGNALS)
# define NO_FPE_SIGNALS
#endif
@@ -230,9 +231,14 @@ EXTERN_FUNCTION(int, real_printf, (const char *fmt, ...));
** Data types:
**
** Eterm: A tagged erlang term (possibly 64 bits)
+** BeamInstr: A beam code instruction unit, possibly larger than Eterm, not smaller.
** UInt: An unsigned integer exactly as large as an Eterm.
** SInt: A signed integer exactly as large as an eterm and therefor large
** enough to hold the return value of the signed_val() macro.
+** UWord: An unsigned integer at least as large as a void * and also as large
+** or larger than an Eterm
+** SWord: A signed integer at least as large as a void * and also as large
+** or larger than an Eterm
** Uint32: An unsigned integer of 32 bits exactly
** Sint32: A signed integer of 32 bits exactly
** Uint16: An unsigned integer of 16 bits exactly
@@ -253,11 +259,43 @@ EXTERN_FUNCTION(int, real_printf, (const char *fmt, ...));
#else
#error Neither 32 nor 64 bit architecture
#endif
+#ifdef ARCH_64
+# ifdef HALFWORD_HEAP_EMULATOR
+# define HALFWORD_HEAP 1
+# define HALFWORD_ASSERT 0
+# else
+# define HALFWORD_HEAP 0
+# define HALFWORD_ASSERT 0
+# endif
+#endif
#if SIZEOF_VOID_P != SIZEOF_SIZE_T
#error sizeof(void*) != sizeof(size_t)
#endif
+#if HALFWORD_HEAP
+
+#if SIZEOF_INT == 4
+typedef unsigned int Eterm;
+typedef unsigned int Uint;
+typedef int Sint;
+#define ERTS_SIZEOF_ETERM SIZEOF_INT
+#else
+#error Found no appropriate type to use for 'Eterm', 'Uint' and 'Sint'
+#endif
+
+#if SIZEOF_VOID_P == SIZEOF_LONG
+typedef unsigned long UWord;
+typedef long SWord;
+#elif SIZEOF_VOID_P == SIZEOF_INT
+typedef unsigned int UWord;
+typedef int SWord;
+#else
+#error Found no appropriate type to use for 'Eterm', 'Uint' and 'Sint'
+#endif
+
+#else /* !HALFWORD_HEAP */
+
#if SIZEOF_VOID_P == SIZEOF_LONG
typedef unsigned long Eterm;
typedef unsigned long Uint;
@@ -272,6 +310,13 @@ typedef int Sint;
#error Found no appropriate type to use for 'Eterm', 'Uint' and 'Sint'
#endif
+typedef Uint UWord;
+typedef Sint SWord;
+
+#endif /* HALFWORD_HEAP */
+
+typedef UWord BeamInstr;
+
#ifndef HAVE_INT64
#if SIZEOF_LONG == 8
#define HAVE_INT64 1
diff --git a/erts/emulator/beam/utils.c b/erts/emulator/beam/utils.c
index 31efddc0f2..51c12a0b69 100644
--- a/erts/emulator/beam/utils.c
+++ b/erts/emulator/beam/utils.c
@@ -204,6 +204,25 @@ erl_grow_stack(Eterm** start, Eterm** sp, Eterm** end)
*end = *start + new_size;
*sp = *start + sp_offs;
}
+/*
+ * Helper function for the ESTACK macros defined in global.h.
+ */
+void
+erl_grow_wstack(UWord** start, UWord** sp, UWord** end)
+{
+ Uint old_size = (*end - *start);
+ Uint new_size = old_size * 2;
+ Uint sp_offs = *sp - *start;
+ if (new_size > 2 * DEF_ESTACK_SIZE) {
+ *start = erts_realloc(ERTS_ALC_T_ESTACK, (void *) *start, new_size*sizeof(UWord));
+ } else {
+ UWord* new_ptr = erts_alloc(ERTS_ALC_T_ESTACK, new_size*sizeof(UWord));
+ sys_memcpy(new_ptr, *start, old_size*sizeof(UWord));
+ *start = new_ptr;
+ }
+ *end = *start + new_size;
+ *sp = *start + sp_offs;
+}
/* CTYPE macros */
@@ -354,6 +373,31 @@ erts_bld_uint(Uint **hpp, Uint *szp, Uint ui)
return res;
}
+/*
+ * Erts_bld_uword is more or less similar to erts_bld_uint, but a pointer
+ * can safely be passed.
+ */
+
+Eterm
+erts_bld_uword(Uint **hpp, Uint *szp, UWord uw)
+{
+ Eterm res = THE_NON_VALUE;
+ if (IS_USMALL(0, uw)) {
+ if (hpp)
+ res = make_small((Uint) uw);
+ }
+ else {
+ if (szp)
+ *szp += BIG_UWORD_HEAP_SIZE(uw);
+ if (hpp) {
+ res = uword_to_big(uw, *hpp);
+ *hpp += BIG_UWORD_HEAP_SIZE(uw);
+ }
+ }
+ return res;
+}
+
+
Eterm
erts_bld_uint64(Uint **hpp, Uint *szp, Uint64 ui64)
{
@@ -711,7 +755,7 @@ hash_binary_bytes(Eterm bin, Uint sz, Uint32 hash)
Uint32 make_hash(Eterm term_arg)
{
- DECLARE_ESTACK(stack);
+ DECLARE_WSTACK(stack);
Eterm term = term_arg;
Eterm hash = 0;
unsigned op;
@@ -770,7 +814,7 @@ tail_recur:
Uint y2 = y1 < 0 ? -(Uint)y1 : y1;
UINT32_HASH_STEP(y2, FUNNY_NUMBER2);
-#ifdef ARCH_64
+#if defined(ARCH_64) && !HALFWORD_HEAP
if (y2 >> 32)
UINT32_HASH_STEP(y2 >> 32, FUNNY_NUMBER2);
#endif
@@ -787,7 +831,7 @@ tail_recur:
}
case EXPORT_DEF:
{
- Export* ep = (Export *) (export_val(term))[1];
+ Export* ep = *((Export **) (export_val(term) + 1));
hash = hash * FUNNY_NUMBER11 + ep->code[2];
hash = hash*FUNNY_NUMBER1 +
@@ -809,7 +853,7 @@ tail_recur:
hash = hash*FUNNY_NUMBER2 + funp->fe->old_uniq;
if (num_free > 0) {
if (num_free > 1) {
- ESTACK_PUSH3(stack, (Eterm) &funp->env[1], (num_free-1), MAKE_HASH_FUN_OP);
+ WSTACK_PUSH3(stack, (UWord) &funp->env[1], (num_free-1), MAKE_HASH_FUN_OP);
}
term = funp->env[0];
goto tail_recur;
@@ -837,9 +881,9 @@ tail_recur:
}
case MAKE_HASH_CDR_PRE_OP:
- term = ESTACK_POP(stack);
+ term = (Eterm) WSTACK_POP(stack);
if (is_not_list(term)) {
- ESTACK_PUSH(stack, MAKE_HASH_CDR_POST_OP);
+ WSTACK_PUSH(stack, (UWord) MAKE_HASH_CDR_POST_OP);
goto tail_recur;
}
/* fall through */
@@ -854,13 +898,13 @@ tail_recur:
hash = hash*FUNNY_NUMBER2 + unsigned_val(*list);
if (is_not_list(CDR(list))) {
- ESTACK_PUSH(stack, MAKE_HASH_CDR_POST_OP);
+ WSTACK_PUSH(stack, MAKE_HASH_CDR_POST_OP);
term = CDR(list);
goto tail_recur;
}
list = list_val(CDR(list));
}
- ESTACK_PUSH2(stack, CDR(list), MAKE_HASH_CDR_PRE_OP);
+ WSTACK_PUSH2(stack, CDR(list), MAKE_HASH_CDR_PRE_OP);
term = CAR(list);
goto tail_recur;
}
@@ -888,7 +932,7 @@ tail_recur:
}
d = BIG_DIGIT(ptr, k);
k = sizeof(ErtsDigit);
-#ifdef ARCH_64
+#if defined(ARCH_64) && !HALFWORD_HEAP
if (!(d >> 32))
k /= 2;
#endif
@@ -904,21 +948,21 @@ tail_recur:
Eterm* ptr = tuple_val(term);
Uint arity = arityval(*ptr);
- ESTACK_PUSH3(stack, arity, (Eterm)(ptr+1), arity);
+ WSTACK_PUSH3(stack, (UWord) arity, (UWord)(ptr+1), (UWord) arity);
op = MAKE_HASH_TUPLE_OP;
}/*fall through*/
case MAKE_HASH_TUPLE_OP:
case MAKE_HASH_FUN_OP:
{
- Uint i = ESTACK_POP(stack);
- Eterm* ptr = (Eterm*) ESTACK_POP(stack);
+ Uint i = (Uint) WSTACK_POP(stack);
+ Eterm* ptr = (Eterm*) WSTACK_POP(stack);
if (i != 0) {
term = *ptr;
- ESTACK_PUSH3(stack, (Eterm)(ptr+1), i-1, op);
+ WSTACK_PUSH3(stack, (UWord)(ptr+1), (UWord) i-1, (UWord) op);
goto tail_recur;
}
if (op == MAKE_HASH_TUPLE_OP) {
- Uint32 arity = ESTACK_POP(stack);
+ Uint32 arity = (Uint32) WSTACK_POP(stack);
hash = hash*FUNNY_NUMBER9 + arity;
}
break;
@@ -928,10 +972,10 @@ tail_recur:
erl_exit(1, "Invalid tag in make_hash(0x%X,0x%X)\n", term, op);
return 0;
}
- if (ESTACK_ISEMPTY(stack)) break;
- op = ESTACK_POP(stack);
+ if (WSTACK_ISEMPTY(stack)) break;
+ op = WSTACK_POP(stack);
}
- DESTROY_ESTACK(stack);
+ DESTROY_WSTACK(stack);
return hash;
#undef UINT32_HASH_STEP
@@ -1002,7 +1046,7 @@ Uint32
make_hash2(Eterm term)
{
Uint32 hash;
- Eterm tmp_big[2];
+ DeclareTmpHeapNoproc(tmp_big,2);
/* (HCONST * {2, ..., 14}) mod 2^32 */
#define HCONST_2 0x3c6ef372UL
@@ -1041,7 +1085,6 @@ make_hash2(Eterm term)
} while(0)
#define IS_SSMALL28(x) (((Uint) (((x) >> (28-1)) + 1)) < 2)
-
/* Optimization. Simple cases before declaration of estack. */
if (primary_tag(term) == TAG_PRIMARY_IMMED1) {
switch (term & _TAG_IMMED1_MASK) {
@@ -1070,6 +1113,7 @@ make_hash2(Eterm term)
Eterm tmp;
DECLARE_ESTACK(s);
+ UseTmpHeapNoproc(2);
hash = 0;
for (;;) {
switch (primary_tag(term)) {
@@ -1123,7 +1167,7 @@ make_hash2(Eterm term)
break;
case EXPORT_SUBTAG:
{
- Export* ep = (Export *) (export_val(term))[1];
+ Export* ep = *((Export **) (export_val(term) + 1));
UINT32_HASH_2
(ep->code[2],
@@ -1314,6 +1358,7 @@ make_hash2(Eterm term)
hash2_common:
if (ESTACK_ISEMPTY(s)) {
DESTROY_ESTACK(s);
+ UnUseTmpHeapNoproc(2);
return hash;
}
term = ESTACK_POP(s);
@@ -1332,7 +1377,7 @@ make_hash2(Eterm term)
Uint32 make_broken_hash(Eterm term)
{
Uint32 hash = 0;
- DECLARE_ESTACK(stack);
+ DECLARE_WSTACK(stack);
unsigned op;
tail_recur:
op = tag_val_def(term);
@@ -1346,7 +1391,7 @@ tail_recur:
(atom_tab(atom_val(term))->slot.bucket.hvalue);
break;
case SMALL_DEF:
-#ifdef ARCH_64
+#if defined(ARCH_64) && !HALFWORD_HEAP
{
Sint y1 = signed_val(term);
Uint y2 = y1 < 0 ? -(Uint)y1 : y1;
@@ -1399,7 +1444,7 @@ tail_recur:
case EXPORT_DEF:
{
- Export* ep = (Export *) (export_val(term))[1];
+ Export* ep = *((Export **) (export_val(term) + 1));
hash = hash * FUNNY_NUMBER11 + ep->code[2];
hash = hash*FUNNY_NUMBER1 +
@@ -1421,7 +1466,7 @@ tail_recur:
hash = hash*FUNNY_NUMBER2 + funp->fe->old_uniq;
if (num_free > 0) {
if (num_free > 1) {
- ESTACK_PUSH3(stack, (Eterm) &funp->env[1], (num_free-1), MAKE_HASH_FUN_OP);
+ WSTACK_PUSH3(stack, (UWord) &funp->env[1], (num_free-1), MAKE_HASH_FUN_OP);
}
term = funp->env[0];
goto tail_recur;
@@ -1456,16 +1501,17 @@ tail_recur:
break;
case MAKE_HASH_CDR_PRE_OP:
- term = ESTACK_POP(stack);
+ term = (Eterm) WSTACK_POP(stack);
if (is_not_list(term)) {
- ESTACK_PUSH(stack, MAKE_HASH_CDR_POST_OP);
+ WSTACK_PUSH(stack, (UWord) MAKE_HASH_CDR_POST_OP);
goto tail_recur;
}
/*fall through*/
case LIST_DEF:
{
Eterm* list = list_val(term);
- ESTACK_PUSH2(stack, CDR(list), MAKE_HASH_CDR_PRE_OP);
+ WSTACK_PUSH2(stack, (UWord) CDR(list),
+ (UWord) MAKE_HASH_CDR_PRE_OP);
term = CAR(list);
goto tail_recur;
}
@@ -1538,21 +1584,21 @@ tail_recur:
Eterm* ptr = tuple_val(term);
Uint arity = arityval(*ptr);
- ESTACK_PUSH3(stack, arity, (Eterm)(ptr+1), arity);
+ WSTACK_PUSH3(stack, (UWord) arity, (UWord) (ptr+1), (UWord) arity);
op = MAKE_HASH_TUPLE_OP;
}/*fall through*/
case MAKE_HASH_TUPLE_OP:
case MAKE_HASH_FUN_OP:
{
- Uint i = ESTACK_POP(stack);
- Eterm* ptr = (Eterm*) ESTACK_POP(stack);
+ Uint i = (Uint) WSTACK_POP(stack);
+ Eterm* ptr = (Eterm*) WSTACK_POP(stack);
if (i != 0) {
term = *ptr;
- ESTACK_PUSH3(stack, (Eterm)(ptr+1), i-1, op);
+ WSTACK_PUSH3(stack, (UWord)(ptr+1), (UWord) i-1, (UWord) op);
goto tail_recur;
}
if (op == MAKE_HASH_TUPLE_OP) {
- Uint32 arity = ESTACK_POP(stack);
+ Uint32 arity = (UWord) WSTACK_POP(stack);
hash = hash*FUNNY_NUMBER9 + arity;
}
break;
@@ -1562,11 +1608,11 @@ tail_recur:
erl_exit(1, "Invalid tag in make_broken_hash\n");
return 0;
}
- if (ESTACK_ISEMPTY(stack)) break;
- op = ESTACK_POP(stack);
+ if (WSTACK_ISEMPTY(stack)) break;
+ op = (Uint) WSTACK_POP(stack);
}
- DESTROY_ESTACK(stack);
+ DESTROY_WSTACK(stack);
return hash;
#undef MAKE_HASH_TUPLE_OP
@@ -1869,7 +1915,7 @@ erts_destroy_tmp_dsbuf(erts_dsprintf_buf_t *dsbufp)
int eq(Eterm a, Eterm b)
{
- DECLARE_ESTACK(stack);
+ DECLARE_WSTACK(stack);
Sint sz;
Eterm* aa;
Eterm* bb;
@@ -1887,7 +1933,7 @@ tailrecur_ne:
Eterm atmp = CAR(aval);
Eterm btmp = CAR(bval);
if (atmp != btmp) {
- ESTACK_PUSH2(stack,CDR(bval),CDR(aval));
+ WSTACK_PUSH2(stack,(UWord) CDR(bval),(UWord) CDR(aval));
a = atmp;
b = btmp;
goto tailrecur_ne;
@@ -1957,8 +2003,8 @@ tailrecur_ne:
case EXPORT_SUBTAG:
{
if (is_export(b)) {
- Export* a_exp = (Export *) (export_val(a))[1];
- Export* b_exp = (Export *) (export_val(b))[1];
+ Export* a_exp = *((Export **) (export_val(a) + 1));
+ Export* b_exp = *((Export **) (export_val(b) + 1));
if (a_exp == b_exp) goto pop_next;
}
break; /* not equal */
@@ -2130,32 +2176,32 @@ term_array: /* arrays in 'aa' and 'bb', length in 'sz' */
goto not_equal;
}
if (i > 1) { /* push the rest */
- ESTACK_PUSH3(stack, i-1, (Eterm)(bp+1),
- ((Eterm)(ap+1)) | TAG_PRIMARY_HEADER);
+ WSTACK_PUSH3(stack, i-1, (UWord)(bp+1),
+ ((UWord)(ap+1)) | TAG_PRIMARY_HEADER);
/* We (ab)use TAG_PRIMARY_HEADER to recognize a term_array */
}
goto tailrecur_ne;
}
pop_next:
- if (!ESTACK_ISEMPTY(stack)) {
- Eterm something = ESTACK_POP(stack);
- if (primary_tag(something) == TAG_PRIMARY_HEADER) { /* a term_array */
+ if (!WSTACK_ISEMPTY(stack)) {
+ UWord something = WSTACK_POP(stack);
+ if (primary_tag((Eterm) something) == TAG_PRIMARY_HEADER) { /* a term_array */
aa = (Eterm*) something;
- bb = (Eterm*) ESTACK_POP(stack);
- sz = ESTACK_POP(stack);
+ bb = (Eterm*) WSTACK_POP(stack);
+ sz = WSTACK_POP(stack);
goto term_array;
}
a = something;
- b = ESTACK_POP(stack);
+ b = WSTACK_POP(stack);
goto tailrecur;
}
- DESTROY_ESTACK(stack);
+ DESTROY_WSTACK(stack);
return 1;
not_equal:
- DESTROY_ESTACK(stack);
+ DESTROY_WSTACK(stack);
return 0;
}
@@ -2210,7 +2256,7 @@ static int cmp_atoms(Eterm a, Eterm b)
Sint cmp(Eterm a, Eterm b)
{
- DECLARE_ESTACK(stack);
+ DECLARE_WSTACK(stack);
Eterm* aa;
Eterm* bb;
int i;
@@ -2327,7 +2373,7 @@ tailrecur_ne:
Eterm atmp = CAR(aa);
Eterm btmp = CAR(bb);
if (atmp != btmp) {
- ESTACK_PUSH2(stack,CDR(bb),CDR(aa));
+ WSTACK_PUSH2(stack,(UWord) CDR(bb),(UWord) CDR(aa));
a = atmp;
b = btmp;
goto tailrecur_ne;
@@ -2392,8 +2438,8 @@ tailrecur_ne:
a_tag = EXPORT_DEF;
goto mixed_types;
} else {
- Export* a_exp = (Export *) (export_val(a))[1];
- Export* b_exp = (Export *) (export_val(b))[1];
+ Export* a_exp = *((Export **) (export_val(a) + 1));
+ Export* b_exp = *((Export **) (export_val(b) + 1));
if ((j = cmp_atoms(a_exp->code[0], b_exp->code[0])) != 0) {
RETURN_NEQ(j);
@@ -2581,7 +2627,11 @@ tailrecur_ne:
{
FloatDef f1, f2;
Eterm big;
- Eterm big_buf[2];
+#if HEAP_ON_C_STACK
+ Eterm big_buf[2]; /* If HEAP_ON_C_STACK */
+#else
+ Eterm *big_buf = erts_get_scheduler_data()->cmp_tmp_heap;
+#endif
switch(_NUMBER_CODE(a_tag, b_tag)) {
case SMALL_BIG:
@@ -2644,7 +2694,7 @@ term_array: /* arrays in 'aa' and 'bb', length in 'i' */
}
} else {
/* (ab)Use TAG_PRIMARY_HEADER to recognize a term_array */
- ESTACK_PUSH3(stack, i, (Eterm)bb, (Eterm)aa | TAG_PRIMARY_HEADER);
+ WSTACK_PUSH3(stack, i, (UWord)bb, (UWord)aa | TAG_PRIMARY_HEADER);
goto tailrecur_ne;
}
}
@@ -2654,20 +2704,20 @@ term_array: /* arrays in 'aa' and 'bb', length in 'i' */
goto tailrecur;
pop_next:
- if (!ESTACK_ISEMPTY(stack)) {
- Eterm something = ESTACK_POP(stack);
- if (primary_tag(something) == TAG_PRIMARY_HEADER) { /* a term_array */
+ if (!WSTACK_ISEMPTY(stack)) {
+ UWord something = WSTACK_POP(stack);
+ if (primary_tag((Eterm) something) == TAG_PRIMARY_HEADER) { /* a term_array */
aa = (Eterm*) something;
- bb = (Eterm*) ESTACK_POP(stack);
- i = ESTACK_POP(stack);
+ bb = (Eterm*) WSTACK_POP(stack);
+ i = WSTACK_POP(stack);
goto term_array;
}
- a = something;
- b = ESTACK_POP(stack);
+ a = (Eterm) something;
+ b = (Eterm) WSTACK_POP(stack);
goto tailrecur;
}
- DESTROY_ESTACK(stack);
+ DESTROY_WSTACK(stack);
return 0;
not_equal:
diff --git a/erts/emulator/drivers/common/efile_drv.c b/erts/emulator/drivers/common/efile_drv.c
index 95510a16b2..cc4421b49c 100644
--- a/erts/emulator/drivers/common/efile_drv.c
+++ b/erts/emulator/drivers/common/efile_drv.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1996-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1996-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
/*
@@ -196,9 +196,9 @@ enum e_timer {timer_idle, timer_again, timer_write};
struct t_data;
typedef struct {
- Sint fd;
+ SWord fd;
ErlDrvPort port;
- unsigned key; /* Async queue key */
+ unsigned long key; /* Async queue key */
unsigned flags; /* Original flags from FILE_OPEN. */
void (*invoke)(void *);
struct t_data *d;
@@ -306,7 +306,7 @@ struct t_data
int result_ok;
Efile_error errInfo;
int flags;
- Sint fd;
+ SWord fd;
/**/
Efile_info info;
EFILE_DIR_HANDLE dir_handle; /* Handle to open directory. */
@@ -605,7 +605,7 @@ file_start(ErlDrvPort port, char* command)
}
desc->fd = FILE_FD_INVALID;
desc->port = port;
- desc->key = (unsigned) (Uint) port;
+ desc->key = (unsigned long) (UWord) port;
desc->flags = 0;
desc->invoke = NULL;
desc->d = NULL;
@@ -630,7 +630,7 @@ static void free_data(void *data)
EF_FREE(data);
}
-static void do_close(int flags, Sint fd) {
+static void do_close(int flags, SWord fd) {
if (flags & EFILE_COMPRESSED) {
erts_gzclose((gzFile)(fd));
} else {
@@ -709,7 +709,7 @@ static void reply_Uint_posix_error(file_descriptor *desc, Uint num,
TRACE_C('N');
response[0] = FILE_RESP_NUMERR;
-#if SIZEOF_VOID_P == 4
+#if SIZEOF_VOID_P == 4 || HALFWORD_HEAP
put_int32(0, response+1);
#else
put_int32(num>>32, response+1);
@@ -767,7 +767,7 @@ static int reply_Uint(file_descriptor *desc, Uint result) {
TRACE_C('R');
tmp[0] = FILE_RESP_NUMBER;
-#if SIZEOF_VOID_P == 4
+#if SIZEOF_VOID_P == 4 || HALFWORD_HEAP
put_int32(0, tmp+1);
#else
put_int32(result>>32, tmp+1);
@@ -1620,7 +1620,7 @@ static void invoke_open(void *data)
status = efile_may_openfile(&d->errInfo, d->b);
if (status || (d->errInfo.posix_errno != EISDIR)) {
mode = (d->flags & EFILE_MODE_READ) ? "rb" : "wb";
- d->fd = (Sint) erts_gzopen(d->b, mode);
+ d->fd = (SWord) erts_gzopen(d->b, mode);
if ((gzFile)d->fd) {
status = 1;
} else {
diff --git a/erts/emulator/drivers/unix/ttsl_drv.c b/erts/emulator/drivers/unix/ttsl_drv.c
index 4cd54c073f..d782b044a9 100644
--- a/erts/emulator/drivers/unix/ttsl_drv.c
+++ b/erts/emulator/drivers/unix/ttsl_drv.c
@@ -314,7 +314,7 @@ static ErlDrvData ttysl_start(ErlDrvPort port, char* buf)
sys_sigset(SIGCONT, cont);
sys_sigset(SIGWINCH, winch);
- driver_select(port, (ErlDrvEvent)(Uint)ttysl_fd, ERL_DRV_READ|ERL_DRV_USE, 1);
+ driver_select(port, (ErlDrvEvent)(UWord)ttysl_fd, ERL_DRV_READ|ERL_DRV_USE, 1);
ttysl_port = port;
/* we need to know this when we enter the break handler */
@@ -394,7 +394,7 @@ static void ttysl_stop(ErlDrvData ttysl_data)
stop_lbuf();
stop_termcap();
tty_reset(ttysl_fd);
- driver_select(ttysl_port, (ErlDrvEvent)(Uint)ttysl_fd, ERL_DRV_READ|ERL_DRV_USE, 0);
+ driver_select(ttysl_port, (ErlDrvEvent)(UWord)ttysl_fd, ERL_DRV_READ|ERL_DRV_USE, 0);
sys_sigset(SIGCONT, SIG_DFL);
sys_sigset(SIGWINCH, SIG_DFL);
}
@@ -685,7 +685,7 @@ static void ttysl_from_tty(ErlDrvData ttysl_data, ErlDrvEvent fd)
utf8buf_size = 0;
}
- if ((i = read((int)(Sint)fd, (char *) p, left)) >= 0) {
+ if ((i = read((int)(SWord)fd, (char *) p, left)) >= 0) {
if (p != b) {
i += (p - b);
}
diff --git a/erts/emulator/sys/common/erl_mseg.c b/erts/emulator/sys/common/erl_mseg.c
index f4e21bc05f..4a9bfd5d08 100644
--- a/erts/emulator/sys/common/erl_mseg.c
+++ b/erts/emulator/sys/common/erl_mseg.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2002-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2002-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -83,10 +83,20 @@ static int is_cache_check_scheduled;
static int is_cache_check_requested;
#endif
+#if HALFWORD_HEAP
+static int initialize_pmmap(void);
+static void *pmmap(size_t size);
+static int pmunmap(void *p, size_t size);
+static void *pmremap(void *old_address, size_t old_size,
+ size_t new_size);
+#endif
+
#if HAVE_MMAP
/* Mmap ... */
#define MMAP_PROT (PROT_READ|PROT_WRITE)
+
+
#ifdef MAP_ANON
# define MMAP_FLAGS (MAP_ANON|MAP_PRIVATE)
# define MMAP_FD (-1)
@@ -102,7 +112,11 @@ static int mmap_fd;
# define HAVE_MSEG_RECREATE 0
#endif
+#if HALFWORD_HEAP
+#define CAN_PARTLY_DESTROY 0
+#else
#define CAN_PARTLY_DESTROY 1
+#endif
#else /* #if HAVE_MMAP */
#define CAN_PARTLY_DESTROY 0
#error "Not supported"
@@ -232,6 +246,7 @@ static void thread_safe_init(void)
{
erts_mtx_init(&init_atoms_mutex, "mseg_init_atoms");
erts_mtx_init(&mseg_mutex, "mseg");
+
#ifdef ERTS_THREADS_NO_SMP
main_tid = erts_thr_self();
#endif
@@ -306,10 +321,20 @@ mseg_create(Uint size)
#if defined(ERTS_MSEG_FAKE_SEGMENTS)
seg = erts_sys_alloc(ERTS_ALC_N_INVALID, NULL, size);
#elif HAVE_MMAP
+#if HALFWORD_HEAP
+ seg = pmmap(size);
+#else
seg = (void *) mmap((void *) 0, (size_t) size,
MMAP_PROT, MMAP_FLAGS, MMAP_FD, 0);
if (seg == (void *) MAP_FAILED)
seg = NULL;
+#endif
+#if HALFWORD_HEAP
+ if ((unsigned long) seg & CHECK_POINTER_MASK) {
+ erts_fprintf(stderr,"Pointer mask failure (0x%08lx)\n",(unsigned long) seg);
+ return NULL;
+ }
+#endif
#else
#error "Missing mseg_create() implementation"
#endif
@@ -329,9 +354,11 @@ mseg_destroy(void *seg, Uint size)
#ifdef DEBUG
int res =
#endif
-
+#if HALFWORD_HEAP
+ pmunmap((void *) seg, size);
+#else
munmap((void *) seg, size);
-
+#endif
ASSERT(size % page_size == 0);
ASSERT(res == 0);
#else
@@ -355,12 +382,18 @@ mseg_recreate(void *old_seg, Uint old_size, Uint new_size)
#if defined(ERTS_MSEG_FAKE_SEGMENTS)
new_seg = erts_sys_realloc(ERTS_ALC_N_INVALID, NULL, old_seg, new_size);
#elif HAVE_MREMAP
+#if HALFWORD_HEAP
+ new_seg = (void *) pmremap((void *) old_seg,
+ (size_t) old_size,
+ (size_t) new_size);
+#else
new_seg = (void *) mremap((void *) old_seg,
(size_t) old_size,
(size_t) new_size,
MREMAP_MAYMOVE);
if (new_seg == (void *) MAP_FAILED)
new_seg = NULL;
+#endif
#else
#error "Missing mseg_recreate() implementation"
#endif
@@ -1328,6 +1361,10 @@ erts_mseg_init(ErtsMsegInit_t *init)
erl_exit(ERTS_ABORT_EXIT, "erts_mseg: unable to open /dev/zero\n");
#endif
+#if HAVE_MMAP && HALFWORD_HEAP
+ initialize_pmmap();
+#endif
+
page_size = GET_PAGE_SIZE;
page_shift = 1;
@@ -1450,3 +1487,419 @@ erts_mseg_test(unsigned long op,
}
+#if HALFWORD_HEAP
+/*
+ * Very simple page oriented mmap replacer. Works in the lower
+ * 32 bit address range of a 64bit program.
+ * Implements anonymous mmap mremap and munmap with address order first fit.
+ * The free list is expected to be very short...
+ * To be used for compressed pointers in Erlang halfword emulator
+ * implementation. The MacOS X version is more of a toy, it's not really
+ * for production as the halfword erlang VM relies on Linux specific memory
+ * mapping tricks.
+ */
+
+/*#define HARDDEBUG 1*/
+
+#ifdef __APPLE__
+#define MAP_ANONYMOUS MAP_ANON
+#endif
+
+#define INIT_LOCK() do {erts_mtx_init(&pmmap_mutex, "pmmap");} while(0)
+
+#define TAKE_LOCK() do {erts_mtx_lock(&pmmap_mutex);} while(0)
+
+#define RELEASE_LOCK() do {erts_mtx_unlock(&pmmap_mutex);} while(0)
+
+static erts_mtx_t pmmap_mutex; /* Also needed when !USE_THREADS */
+
+typedef struct _free_block {
+ unsigned long num; /*pages*/
+ struct _free_block *next;
+} FreeBlock;
+
+/* Assigned once and for all */
+static size_t pagsz;
+
+/* Protect with lock */
+static FreeBlock *first;
+
+static size_t round_up_to_pagesize(size_t size)
+{
+ size_t x = size / pagsz;
+
+ if ((size % pagsz)) {
+ ++x;
+ }
+
+ return pagsz * x;
+}
+
+static size_t round_down_to_pagesize(size_t size)
+{
+ size_t x = size / pagsz;
+
+ return pagsz * x;
+}
+
+static void *do_map(void *ptr, size_t sz)
+{
+ void *res;
+
+ if (round_up_to_pagesize(sz) != sz) {
+#ifdef HARDDEBUG
+ fprintf(stderr,"Mapping of address %p with size %ld "
+ "does not map complete pages\r\n",
+ (void *) ptr, (unsigned long) sz);
+#endif
+ return NULL;
+ }
+
+ if (((unsigned long) ptr) % pagsz) {
+#ifdef HARDDEBUG
+ fprintf(stderr,"Mapping of address %p with size %ld "
+ "is not page aligned\r\n",
+ (void *) ptr, (unsigned long) sz);
+#endif
+ return NULL;
+ }
+
+
+ res = mmap(ptr, sz,
+ PROT_READ | PROT_WRITE, MAP_PRIVATE |
+ MAP_ANONYMOUS | MAP_FIXED,
+ -1 , 0);
+
+ if (res == MAP_FAILED) {
+#ifdef HARDDEBUG
+ fprintf(stderr,"Mapping of address %p with size %ld failed!\r\n",
+ (void *) ptr, (unsigned long) sz);
+#endif
+ return NULL;
+ }
+
+ return res;
+}
+
+static int do_unmap(void *ptr, size_t sz)
+{
+ void *res;
+
+ if (round_up_to_pagesize(sz) != sz) {
+#ifdef HARDDEBUG
+ fprintf(stderr,"Mapping of address %p with size %ld "
+ "does not map complete pages\r\n",
+ (void *) ptr, (unsigned long) sz);
+#endif
+ return 1;
+ }
+
+ if (((unsigned long) ptr) % pagsz) {
+#ifdef HARDDEBUG
+ fprintf(stderr,"Mapping of address %p with size %ld "
+ "is not page aligned\r\n",
+ (void *) ptr, (unsigned long) sz);
+#endif
+ return 1;
+ }
+
+
+ res = mmap(ptr, sz,
+ PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE
+ | MAP_FIXED,
+ -1 , 0);
+
+ if (res == MAP_FAILED) {
+#ifdef HARDDEBUG
+ fprintf(stderr,"Mapping of address %p with size %ld failed!\r\n",
+ (void *) ptr, (unsigned long) sz);
+#endif
+ return 1;
+ }
+
+ return 0;
+}
+
+#ifdef __APPLE__
+/*
+ * The first 4 gig's are protected on Macos X for 64bit processes :(
+ * The range 0x1000000000 - 0x10FFFFFFFF is selected as an arbitrary
+ * value of a normally unused range... Real MMAP's will avoid
+ * it and all 32bit compressed pointers can be in that range...
+ * More expensive than on Linux where expansion of compressed
+ * poiters involves no masking (as they are in the first 4 gig's).
+ * It's also very uncertain if the MAP_NORESERVE flag really has
+ * any effect in MacOS X. Swap space may always be allocated...
+ */
+#define SET_RANGE_MIN() /* nothing */
+#define RANGE_MIN 0x1000000000UL
+#define RANGE_MAX 0x1100000000UL
+#define RANGE_MASK (RANGE_MIN)
+#define EXTRA_MAP_FLAGS (MAP_FIXED)
+#else
+static size_t range_min;
+#define SET_RANGE_MIN() do { range_min = (size_t) sbrk(0); } while (0)
+#define RANGE_MIN range_min
+#define RANGE_MAX 0x100000000UL
+#define RANGE_MASK 0UL
+#define EXTRA_MAP_FLAGS (0)
+#endif
+
+static int initialize_pmmap(void)
+{
+ char *p,*q,*rptr;
+ size_t rsz;
+ FreeBlock *initial;
+
+
+ pagsz = getpagesize();
+ SET_RANGE_MIN();
+ if (sizeof(void *) != 8) {
+ erl_exit(1,"Halfword emulator cannot be run in 32bit mode");
+ }
+
+ p = (char *) RANGE_MIN;
+ q = (char *) RANGE_MAX;
+
+ rsz = round_down_to_pagesize(q - p);
+
+ rptr = mmap((void *) p, rsz,
+ PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS |
+ MAP_NORESERVE | EXTRA_MAP_FLAGS,
+ -1 , 0);
+#ifdef HARDDEBUG
+ printf("rsz = %ld, pages = %ld, rptr = %p\r\n",
+ (unsigned long) rsz, (unsigned long) (rsz / pagsz),
+ (void *) rptr);
+#endif
+ if (!do_map(rptr,pagsz)) {
+ erl_exit(1,"Could not actually mmap first page for halfword emulator...\n");
+ }
+ initial = (FreeBlock *) rptr;
+ initial->num = (rsz / pagsz);
+ initial->next = NULL;
+ first = initial;
+ INIT_LOCK();
+ return 0;
+}
+
+#ifdef HARDDEBUG
+static void dump_freelist(void)
+{
+ FreeBlock *p = first;
+
+ while (p) {
+ printf("p = %p\r\np->num = %ld\r\np->next = %p\r\n\r\n",
+ (void *) p, (unsigned long) p->num, (void *) p->next);
+ p = p->next;
+ }
+}
+#endif
+
+
+static void *pmmap(size_t size)
+{
+ size_t real_size = round_up_to_pagesize(size);
+ size_t num_pages = real_size / pagsz;
+ FreeBlock **block;
+ FreeBlock *tail;
+ FreeBlock *res;
+ TAKE_LOCK();
+ for (block = &first;
+ *block != NULL && (*block)->num < num_pages;
+ block = &((*block)->next))
+ ;
+ if (!(*block)) {
+ RELEASE_LOCK();
+ return NULL;
+ }
+ if ((*block)->num == num_pages) {
+ /* nice, perfect fit */
+ res = *block;
+ *block = (*block)->next;
+ } else {
+ tail = (FreeBlock *) (((char *) ((void *) (*block))) + real_size);
+ if (!do_map(tail,pagsz)) {
+#ifdef HARDDEBUG
+ fprintf(stderr, "Could not actually allocate page at %p...\r\n",
+ (void *) tail);
+#endif
+ RELEASE_LOCK();
+ return NULL;
+ }
+ tail->num = (*block)->num - num_pages;
+ tail->next = (*block)->next;
+ res = *block;
+ *block = tail;
+ }
+ RELEASE_LOCK();
+ if (!do_map(res,real_size)) {
+#ifdef HARDDEBUG
+ fprintf(stderr, "Could not actually allocate %ld at %p...\r\n",
+ (unsigned long) real_size, (void *) res);
+#endif
+ return NULL;
+ }
+
+ return (void *) res;
+}
+
+static int pmunmap(void *p, size_t size)
+{
+ size_t real_size = round_up_to_pagesize(size);
+ size_t num_pages = real_size / pagsz;
+ FreeBlock *block;
+ FreeBlock *last;
+ FreeBlock *nb = (FreeBlock *) p;
+
+ if (real_size > pagsz) {
+ if (do_unmap(((char *) p) + pagsz,real_size - pagsz)) {
+ return 1;
+ }
+ }
+
+ TAKE_LOCK();
+
+ last = NULL;
+ block = first;
+ while(block != NULL && ((void *) block) < p) {
+ last = block;
+ block = block->next;
+ }
+
+ if (block != NULL &&
+ ((void *) block) == ((void *) (((char *) p) + real_size))) {
+ /* Merge new free block with following */
+ nb->num = block->num + num_pages;
+ nb->next = block->next;
+ if (do_unmap(block,pagsz)) {
+ RELEASE_LOCK();
+ return 1;
+ }
+ } else {
+ /* just link in */
+ nb->num = num_pages;
+ nb->next = block;
+ }
+ if (last != NULL) {
+ if (p == ((void *) (((char *) last) + (last->num * pagsz)))) {
+ /* Merge with previous */
+ last->num += nb->num;
+ last->next = nb->next;
+ if (do_unmap(nb,pagsz)) {
+ RELEASE_LOCK();
+ return 1;
+ }
+ } else {
+ last->next = nb;
+ }
+ } else {
+ first = nb;
+ }
+ RELEASE_LOCK();
+ return 0;
+}
+
+static void *pmremap(void *old_address, size_t old_size,
+ size_t new_size)
+{
+ size_t new_real_size = round_up_to_pagesize(new_size);
+ size_t new_num_pages = new_real_size / pagsz;
+ size_t old_real_size = round_up_to_pagesize(old_size);
+ size_t old_num_pages = old_real_size / pagsz;
+ if (new_num_pages == old_num_pages) {
+ return old_address;
+ } else if (new_num_pages < old_num_pages) { /* Shrink */
+ size_t nfb_pages = old_num_pages - new_num_pages;
+ size_t nfb_real_size = old_real_size - new_real_size;
+ void *vnfb = (void *) (((char *)old_address) + new_real_size);
+ FreeBlock *nfb = (FreeBlock *) vnfb;
+ FreeBlock **block;
+ TAKE_LOCK();
+ for (block = &first;
+ *block != NULL && (*block) < nfb;
+ block = &((*block)->next))
+ ;
+ if (!(*block) ||
+ (*block) > ((FreeBlock *)(((char *) vnfb) + nfb_real_size))) {
+ /* Normal link in */
+ if (nfb_pages > 1) {
+ if (do_unmap((void *)(((char *) vnfb) + pagsz),
+ (nfb_pages - 1)*pagsz)) {
+ return NULL;
+ }
+ }
+ nfb->next = (*block);
+ nfb->num = nfb_pages;
+ (*block) = nfb;
+ } else { /* block merge */
+ nfb->next = (*block)->next;
+ nfb->num = nfb_pages + (*block)->num;
+ /* unmap also the first page of the next freeblock */
+ (*block) = nfb;
+ if (do_unmap((void *)(((char *) vnfb) + pagsz),
+ nfb_pages*pagsz)) {
+ return NULL;
+ }
+ }
+ RELEASE_LOCK();
+ return old_address;
+ } else { /* Enlarge */
+ FreeBlock **block;
+ void *old_end = (void *) (((char *)old_address) + old_real_size);
+ TAKE_LOCK();
+ for (block = &first;
+ *block != NULL && (*block) < (FreeBlock *) old_address;
+ block = &((*block)->next))
+ ;
+ if ((*block) == NULL || old_end > ((void *) RANGE_MAX) ||
+ (*block) != old_end ||
+ (*block)->num < (new_num_pages - old_num_pages)) {
+ /* cannot extend */
+ void *result;
+ RELEASE_LOCK();
+ result = pmmap(new_size);
+ if (result == NULL) {
+ return NULL;
+ }
+ memcpy(result,old_address,old_size);
+ if (pmunmap(old_address,old_size)) {
+ /* Oups... */
+ pmunmap(result,new_size);
+ return NULL;
+ }
+ return result;
+ } else { /* extend */
+ size_t remaining_pages = (*block)->num -
+ (new_num_pages - old_num_pages);
+ if (!remaining_pages) {
+ void *p = (void *) (((char *) (*block)) + pagsz);
+ void *n = (*block)->next;
+ size_t x = ((*block)->num - 1) * pagsz;
+ if (x > 0) {
+ if (do_map(p,x) == NULL) {
+ RELEASE_LOCK();
+ return NULL;
+ }
+ }
+ (*block) = n;
+ } else {
+ FreeBlock *nfb = (FreeBlock *) ((void *)
+ (((char *) old_address) +
+ new_real_size));
+ void *p = (void *) (((char *) (*block)) + pagsz);
+ if (do_map(p,new_real_size - old_real_size) == NULL) {
+ RELEASE_LOCK();
+ return NULL;
+ }
+ nfb->num = remaining_pages;
+ nfb->next = (*block)->next;
+ (*block) = nfb;
+ }
+ RELEASE_LOCK();
+ return old_address;
+ }
+ }
+}
+
+#endif /* HALFWORD_HEAP */
diff --git a/erts/emulator/sys/common/erl_mseg.h b/erts/emulator/sys/common/erl_mseg.h
index 1c5aa63e90..d8053eb0d9 100644
--- a/erts/emulator/sys/common/erl_mseg.h
+++ b/erts/emulator/sys/common/erl_mseg.h
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2002-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2002-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -58,8 +58,8 @@ typedef struct {
typedef struct {
int cache;
int preserv;
- Uint abs_shrink_th;
- Uint rel_shrink_th;
+ UWord abs_shrink_th;
+ UWord rel_shrink_th;
} ErtsMsegOpt_t;
#define ERTS_MSEG_DEFAULT_OPT_INITIALIZER \
diff --git a/erts/emulator/test/driver_SUITE_data/peek_non_existing_queue_drv.c b/erts/emulator/test/driver_SUITE_data/peek_non_existing_queue_drv.c
index f429a5b51e..2ac86b1ec2 100644
--- a/erts/emulator/test/driver_SUITE_data/peek_non_existing_queue_drv.c
+++ b/erts/emulator/test/driver_SUITE_data/peek_non_existing_queue_drv.c
@@ -127,7 +127,7 @@ static int control(ErlDrvData drv_data,
char **rbuf, int rlen)
{
PeekNonXQDrvData *dp = (PeekNonXQDrvData *) drv_data;
- unsigned int key = 0;
+ unsigned long key = 0;
char *res_str = "ok";
ErlDrvSysInfo si;
driver_system_info(&si, sizeof(ErlDrvSysInfo));
diff --git a/erts/emulator/test/obsolete_SUITE.erl b/erts/emulator/test/obsolete_SUITE.erl
index 33c4726699..b191f84ee0 100644
--- a/erts/emulator/test/obsolete_SUITE.erl
+++ b/erts/emulator/test/obsolete_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -32,9 +32,9 @@
all(doc) -> [];
all(suite) ->
- case catch erlang:system_info(wordsize) of
+ case catch erlang:system_info({wordsize,external}) of
4 -> [erl_threads];
- _ -> {skip, "Only expected to work on 32-bit architectures"}
+ _ -> {skip, "Only expected to work on true 32-bit architectures"}
end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/erts/emulator/test/system_info_SUITE.erl b/erts/emulator/test/system_info_SUITE.erl
index e782d2f293..ba433d4e11 100644
--- a/erts/emulator/test/system_info_SUITE.erl
+++ b/erts/emulator/test/system_info_SUITE.erl
@@ -35,12 +35,12 @@
%-compile(export_all).
-export([all/1, init_per_testcase/2, fin_per_testcase/2]).
--export([process_count/1, system_version/1, misc_smoke_tests/1, heap_size/1]).
+-export([process_count/1, system_version/1, misc_smoke_tests/1, heap_size/1, wordsize/1]).
-define(DEFAULT_TIMEOUT, ?t:minutes(2)).
all(doc) -> [];
-all(suite) -> [process_count, system_version, misc_smoke_tests, heap_size].
+all(suite) -> [process_count, system_version, misc_smoke_tests, heap_size, wordsize].
init_per_testcase(_Case, Config) when is_list(Config) ->
Dog = ?t:timetrap(?DEFAULT_TIMEOUT),
@@ -145,3 +145,23 @@ heap_size(Config) when is_list(Config) ->
?line Hmin = proplists:get_value(min_heap_size, GCinf),
ok.
+wordsize(suite) ->
+ [];
+wordsize(doc) ->
+ ["Tests the various wordsize variants"];
+wordsize(Config) when is_list(Config) ->
+ ?line A = erlang:system_info(wordsize),
+ ?line true = is_integer(A),
+ ?line A = erlang:system_info({wordsize,internal}),
+ ?line B = erlang:system_info({wordsize,external}),
+ ?line true = A =< B,
+ case {B,A} of
+ {4,4} ->
+ {comment, "True 32-bit emulator"};
+ {8,8} ->
+ {comment, "True 64-bit emulator"};
+ {8,4} ->
+ {comment, "Halfword 64-bit emulator"};
+ Other ->
+ exit({unexpected_wordsizes,Other})
+ end.
diff --git a/erts/emulator/utils/beam_makeops b/erts/emulator/utils/beam_makeops
index 4a859c3094..de19a2e35b 100755
--- a/erts/emulator/utils/beam_makeops
+++ b/erts/emulator/utils/beam_makeops
@@ -1,20 +1,20 @@
#!/usr/bin/env perl
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 1998-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 1998-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
use strict;
@@ -499,7 +499,11 @@ sub emulator_output {
print "\n";
print "#ifdef ARCH_64\n";
print "# define BEAM_LOOSE_MASK 0x1FFFUL\n";
+ print "#if HALFWORD_HEAP\n";
+ print "# define BEAM_TIGHT_MASK 0x1FFCUL\n";
+ print "#else\n";
print "# define BEAM_TIGHT_MASK 0x1FF8UL\n";
+ print "#endif\n";
print "# define BEAM_LOOSE_SHIFT 16\n";
print "# define BEAM_TIGHT_SHIFT 16\n";
print "#else\n";
@@ -813,7 +817,7 @@ sub basic_generator {
#
if ($flags =~ /-pack/ && $hot) {
- ($prefix, $pack_spec, @args) = &do_pack(@args);
+ ($prefix, $pack_spec, @args) = &do_pack(@args);
}
#
@@ -907,16 +911,16 @@ sub basic_generator {
my($code);
if (defined $macro{$name}) {
my($macro_code) = "$prefix$macro(" . join(', ', @f) . ");";
- $var_decls .= "Uint tmp_packed1;"
+ $var_decls .= "BeamInstr tmp_packed1;"
if $macro_code =~ /tmp_packed1/;
- $var_decls .= "Uint tmp_packed2;"
+ $var_decls .= "BeamInstr tmp_packed2;"
if $macro_code =~ /tmp_packed2/;
if ($flags =~ /-nonext/) {
$code = "$macro_code\n";
} else {
$code = join("\n",
"{ $var_decls",
- "Eterm* next;",
+ "BeamInstr* next;",
"PreFetch($size, next);",
"$macro_code",
"NextPF($size, next);",
diff --git a/erts/emulator/utils/make_tables b/erts/emulator/utils/make_tables
index b5391234cf..918ef62094 100755
--- a/erts/emulator/utils/make_tables
+++ b/erts/emulator/utils/make_tables
@@ -1,20 +1,20 @@
#!/usr/bin/env perl
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 1999-2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 1999-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
use strict;
@@ -184,7 +184,7 @@ for ($i = 0; $i < @bif; $i++) {
my $arity = $bif[$i]->[2];
my $args = join(', ', 'Process*', ('Eterm') x $arity);
print "Eterm $bif[$i]->[3]($args);\n";
- print "Eterm wrap_$bif[$i]->[3]($args, Uint *I);\n";
+ print "Eterm wrap_$bif[$i]->[3]($args, UWord *I);\n";
}
print "#endif\n";
@@ -225,15 +225,15 @@ for ($i = 0; $i < @bif; $i++) {
for ($arg = 1; $arg <= $arity; $arg++) {
print ", Eterm arg$arg";
}
- print ", Uint *I)\n";
+ print ", UWord *I)\n";
print "{\n";
print " return erts_bif_trace($i, p";
for ($arg = 1; $arg <= 3; $arg++) {
if ($arg <= $arity) {
print ", arg$arg";
- } elsif ($arg == ($arity + 1)) {
- # Place I in correct position
- print ", (Eterm) I";
+ #} elsif ($arg == ($arity + 1)) {
+ # # Place I in correct position
+ # print ", (Eterm) I";
} else {
print ", 0";
}
diff --git a/erts/include/erl_int_sizes_config.h.in b/erts/include/erl_int_sizes_config.h.in
index ef49995732..4b8a8e1b98 100644
--- a/erts/include/erl_int_sizes_config.h.in
+++ b/erts/include/erl_int_sizes_config.h.in
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2004-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2004-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -31,3 +31,6 @@
/* The number of bytes in a long long. */
#undef SIZEOF_LONG_LONG
+
+/* Define if building a halfword-heap 64bit emulator (needed for NIF's) */
+#undef HALFWORD_HEAP_EMULATOR
diff --git a/erts/preloaded/ebin/erl_prim_loader.beam b/erts/preloaded/ebin/erl_prim_loader.beam
index 304ac41dce..afd8a90b3f 100644
--- a/erts/preloaded/ebin/erl_prim_loader.beam
+++ b/erts/preloaded/ebin/erl_prim_loader.beam
Binary files differ
diff --git a/erts/preloaded/ebin/erlang.beam b/erts/preloaded/ebin/erlang.beam
index 21e5525b2f..4ec84948d8 100644
--- a/erts/preloaded/ebin/erlang.beam
+++ b/erts/preloaded/ebin/erlang.beam
Binary files differ
diff --git a/erts/preloaded/ebin/init.beam b/erts/preloaded/ebin/init.beam
index 8ccc553c13..c3e746f3ee 100644
--- a/erts/preloaded/ebin/init.beam
+++ b/erts/preloaded/ebin/init.beam
Binary files differ
diff --git a/erts/preloaded/ebin/otp_ring0.beam b/erts/preloaded/ebin/otp_ring0.beam
index 8ae73ea9a7..4b2d8bb2de 100644
--- a/erts/preloaded/ebin/otp_ring0.beam
+++ b/erts/preloaded/ebin/otp_ring0.beam
Binary files differ
diff --git a/erts/preloaded/ebin/prim_file.beam b/erts/preloaded/ebin/prim_file.beam
index 3acda843fd..2916baaa77 100644
--- a/erts/preloaded/ebin/prim_file.beam
+++ b/erts/preloaded/ebin/prim_file.beam
Binary files differ
diff --git a/erts/preloaded/ebin/prim_inet.beam b/erts/preloaded/ebin/prim_inet.beam
index 9457b6d360..46912e2bea 100644
--- a/erts/preloaded/ebin/prim_inet.beam
+++ b/erts/preloaded/ebin/prim_inet.beam
Binary files differ
diff --git a/erts/preloaded/ebin/prim_zip.beam b/erts/preloaded/ebin/prim_zip.beam
index 6837cb4661..ccf8aff6f6 100644
--- a/erts/preloaded/ebin/prim_zip.beam
+++ b/erts/preloaded/ebin/prim_zip.beam
Binary files differ
diff --git a/erts/preloaded/ebin/zlib.beam b/erts/preloaded/ebin/zlib.beam
index 4e4f85d312..ccd597ba68 100644
--- a/erts/preloaded/ebin/zlib.beam
+++ b/erts/preloaded/ebin/zlib.beam
Binary files differ
diff --git a/erts/preloaded/src/prim_zip.erl b/erts/preloaded/src/prim_zip.erl
index 3f5a5b9721..6a9856fdad 100644
--- a/erts/preloaded/src/prim_zip.erl
+++ b/erts/preloaded/src/prim_zip.erl
@@ -65,34 +65,55 @@ filter_fun() ->
open(F) ->
open(filter_fun(), undefined, F).
-open(FilterFun, FilterAcc, F) ->
- case ?CATCH do_open(FilterFun, FilterAcc, F) of
- {ok, PrimZip, Acc} ->
- {ok, PrimZip, Acc};
- Error ->
- {error, Error}
- end.
+open(FilterFun, FilterAcc, F) when is_function(FilterFun, 2) ->
+ try
+ do_open(FilterFun, FilterAcc, F)
+ catch
+ throw:{filter_fun_throw, Reason} ->
+ throw(Reason);
+ throw:InternalReason ->
+ {error, InternalReason};
+ Class:Reason ->
+ erlang:error(erlang:raise(Class, Reason, erlang:get_stacktrace()))
+ end;
+open(_, _, _) ->
+ {error, einval}.
do_open(FilterFun, FilterAcc, F) ->
Input = get_zip_input(F),
In0 = Input({open, F, [read, binary, raw]}, []),
Z = zlib:open(),
PrimZip = #primzip{files = [], zlib = Z, in = In0, input = Input},
- {PrimZip2, FilterAcc2} = get_central_dir(PrimZip, FilterFun, FilterAcc),
- {ok, PrimZip2, FilterAcc2}.
+ try
+ {PrimZip2, FilterAcc2} = get_central_dir(PrimZip, FilterFun, FilterAcc),
+ {ok, PrimZip2, FilterAcc2}
+ catch
+ Class:Reason ->
+ close(PrimZip),
+ erlang:error(erlang:raise(Class, Reason, erlang:get_stacktrace()))
+ end.
%% iterate over all files in a zip archive
-foldl(FilterFun, FilterAcc, #primzip{files = Files} = PrimZip) ->
- case ?CATCH do_foldl(FilterFun, FilterAcc, Files, [], PrimZip, PrimZip) of
- {ok, FilterAcc2, PrimZip2} -> {ok, PrimZip2, FilterAcc2};
- Error -> {error, Error}
+foldl(FilterFun, FilterAcc, #primzip{files = Files} = PrimZip)
+ when is_function(FilterFun, 2) ->
+ try
+ {ok, FilterAcc2, PrimZip2} =
+ do_foldl(FilterFun, FilterAcc, Files, [], PrimZip, PrimZip),
+ {ok, PrimZip2, FilterAcc2}
+ catch
+ throw:{filter_fun_throw, Reason} ->
+ throw(Reason);
+ throw:InternalReason ->
+ {error, InternalReason};
+ Class:Reason ->
+ erlang:error(erlang:raise(Class, Reason, erlang:get_stacktrace()))
end;
foldl(_, _, _) ->
{error, einval}.
do_foldl(FilterFun, FilterAcc, [PF | Tail], Acc0, PrimZip, PrimZipOrig) ->
#primzip_file{name = F, get_info = GetInfo, get_bin = GetBin} = PF,
- case FilterFun({F, GetInfo, GetBin}, FilterAcc) of
+ try FilterFun({F, GetInfo, GetBin}, FilterAcc) of
{Continue, Include, FilterAcc2} ->
Acc1 = include_acc(Include, PF, Acc0),
case Continue of
@@ -103,6 +124,9 @@ do_foldl(FilterFun, FilterAcc, [PF | Tail], Acc0, PrimZip, PrimZipOrig) ->
end;
FilterRes ->
throw({illegal_filter, FilterRes})
+ catch
+ throw:Reason ->
+ throw({filter_fun_throw, Reason})
end;
do_foldl(_FilterFun, FilterAcc, [], Acc, PrimZip, _PrimZipOrig) ->
{ok, FilterAcc, PrimZip#primzip{files = reverse(Acc)}}.
@@ -121,12 +145,14 @@ include_acc(Include, PF, Acc) ->
List when is_list(List) ->
%% Add new entries
Fun = fun(I, A) -> include_acc(I, PF, A) end,
- lists_foldl(Fun, Acc, List)
+ lists_foldl(Fun, Acc, List);
+ Bad ->
+ throw({illegal_filter, Bad})
end.
lists_foldl(F, Accu, [Hd|Tail]) ->
lists_foldl(F, F(Hd, Accu), Tail);
-lists_foldl(F, Accu, []) when is_function(F, 2) ->
+lists_foldl(F, Accu, []) when is_function(F, 2) ->
Accu.
%% close a zip archive
@@ -139,7 +165,9 @@ close(_) ->
get_zip_input({F, B}) when is_binary(B), is_list(F) ->
fun binary_io/2;
get_zip_input(F) when is_list(F) ->
- fun prim_file_io/2.
+ fun prim_file_io/2;
+get_zip_input(_) ->
+ throw(einval).
%% get a file from the archive
get_z_file(F, Offset, ChunkSize, #primzip{zlib = Z, in = In0, input = Input}) ->
@@ -218,15 +246,15 @@ get_cd_loop(N, BCD, Acc0, PrimZip, FileName, Offset, CFH, EndOffset, FilterFun,
GetInfo = fun() -> cd_file_header_to_file_info(FileName, CFH, <<>>) end,
GetBin = fun() -> get_z_file(FileName, Offset, Size, PrimZip) end,
PF = #primzip_file{name = FileName, get_info = GetInfo, get_bin = GetBin},
- case FilterFun({FileName, GetInfo, GetBin}, FilterAcc) of
+ try FilterFun({FileName, GetInfo, GetBin}, FilterAcc) of
{Continue, Include, FilterAcc2} ->
Acc1 =
case Include of
- false ->
+ false ->
Acc0;
true ->
[PF | Acc0];
- {true, Nick} ->
+ {true, Nick} ->
[PF#primzip_file{name = Nick} | Acc0];
{true, Nick, GI, GB} ->
PF2 = #primzip_file{name = Nick, get_info = GI, get_bin = GB},
@@ -247,13 +275,16 @@ get_cd_loop(N, BCD, Acc0, PrimZip, FileName, Offset, CFH, EndOffset, FilterFun,
end;
FilterRes ->
throw({illegal_filter, FilterRes})
+ catch
+ throw:Reason ->
+ throw({filter_fun_throw, Reason})
end.
get_file_header(BCD) ->
BCFH =
case BCD of
<<?CENTRAL_FILE_MAGIC:32/little,
- B:(?CENTRAL_FILE_HEADER_SZ-4)/binary,
+ B:(?CENTRAL_FILE_HEADER_SZ-4)/binary,
_/binary>> ->
B;
_ ->
@@ -266,11 +297,11 @@ get_file_header(BCD) ->
ToGet = FileNameLen + ExtraLen + CommentLen,
{B2, BCDRest} =
case BCD of
- <<_:?CENTRAL_FILE_HEADER_SZ/binary,
+ <<_:?CENTRAL_FILE_HEADER_SZ/binary,
G:ToGet/binary,
- Rest/binary>> ->
+ Rest/binary>> ->
{G, Rest};
- _ ->
+ _ ->
throw(bad_central_directory)
end,
FileName = get_filename_from_b2(B2, FileNameLen, ExtraLen, CommentLen),
@@ -319,9 +350,9 @@ prim_file_io({file_info, F}, _) ->
end;
prim_file_io({open, FN, Opts}, _) ->
case ?CATCH prim_file:open(FN, Opts++[binary]) of
- {ok, H} ->
+ {ok, H} ->
H;
- {error, E} ->
+ {error, E} ->
throw(E)
end;
prim_file_io({read, N}, H) ->
@@ -476,7 +507,7 @@ cd_file_header_to_file_info(FileName,
%% FI; % not yet supported, and not widely used
add_extra_info(FI, _) ->
FI.
-%%
+%%
%% unix_extra_field_and_var_from_bin(<<TSize:16/little,
%% ATime:32/little,
%% MTime:32/little,
@@ -500,7 +531,7 @@ dos_date_time_to_datetime(DosDate, DosTime) ->
<<Hour:5, Min:6, Sec:5>> = <<DosTime:16>>,
<<YearFrom1980:7, Month:4, Day:5>> = <<DosDate:16>>,
{{YearFrom1980+1980, Month, Day},
- {Hour, Min, Sec}}.
+ {Hour, Min, Sec}}.
cd_file_header_from_bin(<<VersionMadeBy:16/little,
VersionNeeded:16/little,
@@ -622,7 +653,7 @@ reverse(X) ->
reverse([H|T], Y) ->
reverse(T, [H|Y]);
-reverse([], X) ->
+reverse([], X) ->
X.
last([E|Es]) -> last(E, Es).
diff --git a/lib/appmon/doc/src/appmon_chapter.xml b/lib/appmon/doc/src/appmon_chapter.xml
index 9673a13078..0dab23b549 100644
--- a/lib/appmon/doc/src/appmon_chapter.xml
+++ b/lib/appmon/doc/src/appmon_chapter.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2000</year><year>2009</year>
+ <year>2000</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>Appmon</title>
@@ -226,8 +226,8 @@
<p>In the left frame it is possible to:</p>
<list type="bulleted">
<item>Select which node to supervise.</item>
- <item>Select an application to view it's process tree.</item>
- <item>Select an application to view it's specification.</item>
+ <item>Select an application to view its process tree.</item>
+ <item>Select an application to view its specification.</item>
</list>
<p>The right frame shows the selected information, either the application
specification or the process tree and process information.</p>
diff --git a/lib/asn1/test/Makefile b/lib/asn1/test/Makefile
index 879e51c632..5014eb902b 100644
--- a/lib/asn1/test/Makefile
+++ b/lib/asn1/test/Makefile
@@ -133,9 +133,7 @@ ERL_FILES= $(MODULES:%=%.erl)
HRL_FILES= External.hrl
-TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR))
-
-INSTALL_PROGS= $(TARGET_FILES)
+EMAKEFILE=Emakefile
# ----------------------------------------------------
# Release directory specification
@@ -145,19 +143,20 @@ RELSYSDIR = $(RELEASE_PATH)/asn1_test
# ----------------------------------------------------
# FLAGS
# ----------------------------------------------------
-ERL_COMPILE_FLAGS += -I$(ERL_TOP)/lib/test_server/include \
- -I$(ERL_TOP)/lib/kernel/include
-
+ERL_COMPILE_FLAGS += +warnings_as_errors
EBIN = .
# ----------------------------------------------------
# Targets
# ----------------------------------------------------
-tests debug opt: $(TARGET_FILES) $(SUITE) $(SUITE_BIN) $(SUITE_BIN_V2)
+$(EMAKEFILE): $(ERL_FILES) $(HRL_FILES)
+ $(ERL_TOP)/make/make_emakefile $(ERL_COMPILE_FLAGS) -o$(EBIN) $(MODULES) $(ERL_FILES) >$(EMAKEFILE)
+
+tests debug opt: $(SUITE) $(SUITE_BIN) $(SUITE_BIN_V2) $(EMAKEFILE)
clean:
- rm -f $(TARGET_FILES) $(SUITE) $(SUITE_BIN) $(SUITE_BIN_V2)
+ rm -f $(SUITE) $(SUITE_BIN) $(SUITE_BIN_V2)
rm -f core
docs:
@@ -190,8 +189,7 @@ release_spec: opt
release_tests_spec: opt
$(INSTALL_DIR) $(RELSYSDIR)
- $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR)
- $(INSTALL_DATA) asn1.spec $(INSTALL_PROGS) $(RELSYSDIR)
+ $(INSTALL_DATA) asn1.spec $(EMAKEFILE) $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR)
chmod -f -R u+w $(RELSYSDIR)
@tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -)
$(INSTALL_DIR) $(RELSYSDIR)/asn1_bin_SUITE_data
diff --git a/lib/asn1/test/asn1_SUITE.erl.src b/lib/asn1/test/asn1_SUITE.erl.src
index 53a5cc5284..9d3f03fc4c 100644
--- a/lib/asn1/test/asn1_SUITE.erl.src
+++ b/lib/asn1/test/asn1_SUITE.erl.src
@@ -48,7 +48,7 @@
-compile(export_all).
%%-export([Function/Arity, ...]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
%% records used by test-case default
-record('Def1',{
diff --git a/lib/asn1/test/asn1_app_test.erl b/lib/asn1/test/asn1_app_test.erl
index 8ee42d3ec3..23a7e691e7 100644
--- a/lib/asn1/test/asn1_app_test.erl
+++ b/lib/asn1/test/asn1_app_test.erl
@@ -1,43 +1,29 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2005-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
%%----------------------------------------------------------------------
-%% Purpose: Verify the application specifics of the Megaco application
+%% Purpose: Verify the application specifics of the asn1 application
%%----------------------------------------------------------------------
-module(asn1_app_test).
-compile(export_all).
-%-include("megaco_test_lib.hrl").
-
-
-% t() -> megaco_test_lib:t(?MODULE).
-% t(Case) -> megaco_test_lib:t({?MODULE, Case}).
-
-
-% %% Test server callbacks
-% init_per_testcase(Case, Config) ->
-% megaco_test_lib:init_per_testcase(Case, Config).
-
-% fin_per_testcase(Case, Config) ->
-% megaco_test_lib:fin_per_testcase(Case, Config).
-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
all(suite) ->
@@ -54,7 +40,7 @@ all(suite) ->
app_init(suite) -> [];
app_init(doc) -> [];
-app_init(Config) when list(Config) ->
+app_init(Config) when is_list(Config) ->
case is_app(asn1) of
{ok, AppFile} ->
io:format("AppFile: ~n~p~n", [AppFile]),
@@ -76,7 +62,7 @@ is_app(App) ->
app_fin(suite) -> [];
app_fin(doc) -> [];
-app_fin(Config) when list(Config) ->
+app_fin(Config) when is_list(Config) ->
Config.
@@ -86,7 +72,7 @@ fields(suite) ->
[];
fields(doc) ->
[];
-fields(Config) when list(Config) ->
+fields(Config) when is_list(Config) ->
AppFile = key1search(app_file, Config),
Fields = [vsn, description, modules, registered, applications],
case check_fields(Fields, AppFile, []) of
@@ -117,7 +103,7 @@ modules(suite) ->
[];
modules(doc) ->
[];
-modules(Config) when list(Config) ->
+modules(Config) when is_list(Config) ->
AppFile = key1search(app_file, Config),
Mods = key1search(modules, AppFile),
EbinList = get_ebin_mods(asn1),
@@ -188,7 +174,7 @@ exportall(suite) ->
[];
exportall(doc) ->
[];
-exportall(Config) when list(Config) ->
+exportall(Config) when is_list(Config) ->
AppFile = key1search(app_file, Config),
Mods = key1search(modules, AppFile),
check_export_all(Mods).
@@ -221,7 +207,7 @@ app_depend(suite) ->
[];
app_depend(doc) ->
[];
-app_depend(Config) when list(Config) ->
+app_depend(Config) when is_list(Config) ->
AppFile = key1search(app_file, Config),
Apps = key1search(applications, AppFile),
check_apps(Apps).
diff --git a/lib/asn1/test/asn1_appup_test.erl b/lib/asn1/test/asn1_appup_test.erl
index 644c0f7d03..81701328a6 100644
--- a/lib/asn1/test/asn1_appup_test.erl
+++ b/lib/asn1/test/asn1_appup_test.erl
@@ -1,43 +1,29 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2005-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
%%----------------------------------------------------------------------
-%% Purpose: Verify the application specifics of the Megaco application
+%% Purpose: Verify the application specifics of the asn1 application
%%----------------------------------------------------------------------
-module(asn1_appup_test).
-compile(export_all).
-%-include("megaco_test_lib.hrl").
-
-
-%t() -> megaco_test_lib:t(?MODULE).
-%t(Case) -> megaco_test_lib:t({?MODULE, Case}).
-
-
-%% Test server callbacks
-% init_per_testcase(Case, Config) ->
-% megaco_test_lib:init_per_testcase(Case, Config).
-
-% fin_per_testcase(Case, Config) ->
-% megaco_test_lib:fin_per_testcase(Case, Config).
-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
all(suite) ->
@@ -51,7 +37,7 @@ all(suite) ->
appup_init(suite) -> [];
appup_init(doc) -> [];
-appup_init(Config) when list(Config) ->
+appup_init(Config) when is_list(Config) ->
AppFile = file_name(asn1, ".app"),
AppupFile = file_name(asn1, ".appup"),
[{app_file, AppFile}, {appup_file, AppupFile}|Config].
@@ -64,7 +50,7 @@ file_name(App, Ext) ->
appup_fin(suite) -> [];
appup_fin(doc) -> [];
-appup_fin(Config) when list(Config) ->
+appup_fin(Config) when is_list(Config) ->
Config.
@@ -74,7 +60,7 @@ appup(suite) ->
[];
appup(doc) ->
"perform a simple check of the appup file";
-appup(Config) when list(Config) ->
+appup(Config) when is_list(Config) ->
AppupFile = key1search(appup_file, Config),
AppFile = key1search(app_file, Config),
Modules = modules(AppFile),
@@ -161,14 +147,14 @@ check_instructions(UpDown, [Instr|Instrs], AllInstr, Good, Bad, Modules) ->
%% A new module is added
check_instruction(up, {add_module, Module}, _, Modules)
- when atom(Module) ->
+ when is_atom(Module) ->
d("check_instruction -> entry when up-add_module instruction with"
"~n Module: ~p", [Module]),
check_module(Module, Modules);
%% An old module is re-added
check_instruction(down, {add_module, Module}, _, Modules)
- when atom(Module) ->
+ when is_atom(Module) ->
d("check_instruction -> entry when down-add_module instruction with"
"~n Module: ~p", [Module]),
case (catch check_module(Module, Modules)) of
@@ -182,7 +168,7 @@ check_instruction(down, {add_module, Module}, _, Modules)
%% - the module has been removed from the app-file.
%% - check that no module depends on this (removed) module
check_instruction(up, {remove, {Module, Pre, Post}}, _, Modules)
- when atom(Module), atom(Pre), atom(Post) ->
+ when is_atom(Module), is_atom(Pre), is_atom(Post) ->
d("check_instruction -> entry when up-remove instruction with"
"~n Module: ~p"
"~n Pre: ~p"
@@ -198,7 +184,7 @@ check_instruction(up, {remove, {Module, Pre, Post}}, _, Modules)
%% Removing a module on downgrade: the module exist
%% in the app-file.
check_instruction(down, {remove, {Module, Pre, Post}}, AllInstr, Modules)
- when atom(Module), atom(Pre), atom(Post) ->
+ when is_atom(Module), is_atom(Pre), is_atom(Post) ->
d("check_instruction -> entry when down-remove instruction with"
"~n Module: ~p"
"~n Pre: ~p"
@@ -214,7 +200,7 @@ check_instruction(down, {remove, {Module, Pre, Post}}, AllInstr, Modules)
check_instruction(_, {load_module, Module, Pre, Post, Depend},
AllInstr, Modules)
- when atom(Module), atom(Pre), atom(Post), list(Depend) ->
+ when is_atom(Module), is_atom(Pre), is_atom(Post), is_list(Depend) ->
d("check_instruction -> entry when load_module instruction with"
"~n Module: ~p"
"~n Pre: ~p"
@@ -228,7 +214,7 @@ check_instruction(_, {load_module, Module, Pre, Post, Depend},
check_instruction(_, {update, Module, Change, Pre, Post, Depend},
AllInstr, Modules)
- when atom(Module), atom(Pre), atom(Post), list(Depend) ->
+ when is_atom(Module), is_atom(Pre), is_atom(Post), is_list(Depend) ->
d("check_instruction -> entry when update instruction with"
"~n Module: ~p"
"~n Change: ~p"
@@ -244,7 +230,7 @@ check_instruction(_, {update, Module, Change, Pre, Post, Depend},
check_instruction(_, {apply, {Module, Function, Args}},
_AllInstr, Modules)
- when atom(Module), atom(Function), list(Args) ->
+ when is_atom(Module), is_atom(Function), is_list(Args) ->
d("check_instruction -> entry when apply instruction with"
"~n Module: ~p"
"~n Function: ~p"
@@ -289,13 +275,13 @@ instruction_module(Instr) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-check_version(V) when list(V) ->
+check_version(V) when is_list(V) ->
ok;
check_version(V) ->
error({bad_version, V}).
-check_module(M, Modules) when atom(M) ->
+check_module(M, Modules) when is_atom(M) ->
case lists:member(M,Modules) of
true ->
ok;
@@ -307,7 +293,7 @@ check_module(M, _) ->
check_apply(Module,Function,Args) ->
case (catch Module:module_info()) of
- Info when list(Info) ->
+ Info when is_list(Info) ->
check_exported(Function,Args,Info);
{'EXIT',{undef,_}} ->
error({not_existing_module,Module})
@@ -326,11 +312,11 @@ check_exported(Function,Args,Info) ->
error({bad_export,Info})
end.
-check_module_depend(M, [], _) when atom(M) ->
+check_module_depend(M, [], _) when is_atom(M) ->
d("check_module_depend -> entry with"
"~n M: ~p", [M]),
ok;
-check_module_depend(M, Deps, Modules) when atom(M), list(Deps) ->
+check_module_depend(M, Deps, Modules) when is_atom(M), is_list(Deps) ->
d("check_module_depend -> entry with"
"~n M: ~p"
"~n Deps: ~p"
diff --git a/lib/asn1/test/asn1_test_lib.erl b/lib/asn1/test/asn1_test_lib.erl
index 2884c79216..26cbdeb940 100644
--- a/lib/asn1/test/asn1_test_lib.erl
+++ b/lib/asn1/test/asn1_test_lib.erl
@@ -22,7 +22,7 @@
-export([ticket_7407_compile/2,ticket_7407_code/1, ticket_7678/2,
ticket_7708/2, ticket_7763/1, ticket_7876/3]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
ticket_7407_compile(Config,Option) ->
diff --git a/lib/asn1/test/asn1_wrapper.erl b/lib/asn1/test/asn1_wrapper.erl
index 553f0b062c..d515b99ac2 100644
--- a/lib/asn1/test/asn1_wrapper.erl
+++ b/lib/asn1/test/asn1_wrapper.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -26,7 +26,7 @@
encode(Module,Type,Value) ->
case asn1rt:encode(Module,Type,Value) of
- {ok,X} when binary(X) ->
+ {ok,X} when is_binary(X) ->
{ok, binary_to_list(X)};
{ok,X} ->
{ok, binary_to_list(list_to_binary(X))};
@@ -38,21 +38,21 @@ decode(Module,Type,Bytes) ->
case Module:encoding_rule() of
ber ->
asn1rt:decode(Module,Type,Bytes);
- ber_bin when binary(Bytes) ->
+ ber_bin when is_binary(Bytes) ->
asn1rt:decode(Module,Type,Bytes);
ber_bin ->
asn1rt:decode(Module,Type,list_to_binary(Bytes));
- ber_bin_v2 when binary(Bytes) ->
+ ber_bin_v2 when is_binary(Bytes) ->
asn1rt:decode(Module,Type,Bytes);
ber_bin_v2 ->
asn1rt:decode(Module,Type,list_to_binary(Bytes));
per ->
asn1rt:decode(Module,Type,Bytes);
- per_bin when binary(Bytes) ->
+ per_bin when is_binary(Bytes) ->
asn1rt:decode(Module,Type,Bytes);
per_bin ->
asn1rt:decode(Module,Type,list_to_binary(Bytes));
- uper_bin when binary(Bytes) ->
+ uper_bin when is_binary(Bytes) ->
asn1rt:decode(Module,Type,Bytes);
uper_bin ->
asn1rt:decode(Module,Type,list_to_binary(Bytes))
diff --git a/lib/asn1/test/ber_decode_error.erl b/lib/asn1/test/ber_decode_error.erl
index aa3b0122fd..96d6545636 100644
--- a/lib/asn1/test/ber_decode_error.erl
+++ b/lib/asn1/test/ber_decode_error.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -21,7 +21,7 @@
-export([run/1, compile/3]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
compile(Config,Rules,Options) ->
diff --git a/lib/asn1/test/choice_extension.erl b/lib/asn1/test/choice_extension.erl
index 843704ee9e..85e0936ebf 100644
--- a/lib/asn1/test/choice_extension.erl
+++ b/lib/asn1/test/choice_extension.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -21,7 +21,7 @@
-export([run/0, compile/3]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
compile(Config,Rules,Options) ->
diff --git a/lib/asn1/test/h323test.erl b/lib/asn1/test/h323test.erl
index 60d2c39be0..5545dd45b9 100644
--- a/lib/asn1/test/h323test.erl
+++ b/lib/asn1/test/h323test.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -21,7 +21,7 @@
-compile(export_all).
-export([compile/3,run/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
compile(Config,Rules,Options) ->
?line DataDir = ?config(data_dir,Config),
diff --git a/lib/asn1/test/testChoExtension.erl b/lib/asn1/test/testChoExtension.erl
index 125dfaa3bd..5e149ed247 100644
--- a/lib/asn1/test/testChoExtension.erl
+++ b/lib/asn1/test/testChoExtension.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -22,7 +22,7 @@
-export([compile/3]).
-export([extension/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
compile(Config,Rules,Options) ->
diff --git a/lib/asn1/test/testChoExternal.erl b/lib/asn1/test/testChoExternal.erl
index 5f804d9d7f..b6586b616b 100644
--- a/lib/asn1/test/testChoExternal.erl
+++ b/lib/asn1/test/testChoExternal.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -23,7 +23,7 @@
-export([compile/3]).
-export([external/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include("External.hrl").
diff --git a/lib/asn1/test/testChoOptional.erl b/lib/asn1/test/testChoOptional.erl
index 2d969391d0..61a1955d28 100644
--- a/lib/asn1/test/testChoOptional.erl
+++ b/lib/asn1/test/testChoOptional.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -24,7 +24,7 @@
-export([optional/1]).
%-include("ChoOptional.hrl").
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include("External.hrl").
diff --git a/lib/asn1/test/testChoOptionalImplicitTag.erl b/lib/asn1/test/testChoOptionalImplicitTag.erl
index 30addf2e20..e28353cb5a 100644
--- a/lib/asn1/test/testChoOptionalImplicitTag.erl
+++ b/lib/asn1/test/testChoOptionalImplicitTag.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -24,7 +24,7 @@
-export([optional/1]).
%-include("ChoOptional.hrl").
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include("External.hrl").
diff --git a/lib/asn1/test/testChoPrim.erl b/lib/asn1/test/testChoPrim.erl
index 7fa6164b5a..f037db1c5d 100644
--- a/lib/asn1/test/testChoPrim.erl
+++ b/lib/asn1/test/testChoPrim.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -23,7 +23,7 @@
-export([bool/1]).
-export([int/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
compile(Config,Rules,Options) ->
diff --git a/lib/asn1/test/testChoRecursive.erl b/lib/asn1/test/testChoRecursive.erl
index f8c5e60f55..36e23e2e03 100644
--- a/lib/asn1/test/testChoRecursive.erl
+++ b/lib/asn1/test/testChoRecursive.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -23,7 +23,7 @@
-export([compile/3]).
-export([recursive/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-record('ChoRec_something',{a, b, c}).
-record('ChoRec2_something',{a, b, c}).
diff --git a/lib/asn1/test/testChoTypeRefCho.erl b/lib/asn1/test/testChoTypeRefCho.erl
index 341a77c21b..f381d9078d 100644
--- a/lib/asn1/test/testChoTypeRefCho.erl
+++ b/lib/asn1/test/testChoTypeRefCho.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -22,7 +22,7 @@
-export([compile/3]).
-export([choice/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
diff --git a/lib/asn1/test/testChoTypeRefPrim.erl b/lib/asn1/test/testChoTypeRefPrim.erl
index 1ef221819c..8fb9ed9f02 100644
--- a/lib/asn1/test/testChoTypeRefPrim.erl
+++ b/lib/asn1/test/testChoTypeRefPrim.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -22,7 +22,7 @@
-export([compile/3]).
-export([prim/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
diff --git a/lib/asn1/test/testChoTypeRefSeq.erl b/lib/asn1/test/testChoTypeRefSeq.erl
index 2e9aa7c411..45d6209e79 100644
--- a/lib/asn1/test/testChoTypeRefSeq.erl
+++ b/lib/asn1/test/testChoTypeRefSeq.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -22,7 +22,7 @@
-export([compile/3]).
-export([seq/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-record('ChoSeq',{seqInt, seqOs}).
-record('ChoSeqImp',{seqInt, seqOs}).
diff --git a/lib/asn1/test/testChoTypeRefSet.erl b/lib/asn1/test/testChoTypeRefSet.erl
index e4db73c1e3..9869549d7a 100644
--- a/lib/asn1/test/testChoTypeRefSet.erl
+++ b/lib/asn1/test/testChoTypeRefSet.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -22,7 +22,7 @@
-export([compile/3]).
-export([set/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-record('ChoSet',{setInt, setOs}).
-record('ChoSetImp',{setInt, setOs}).
diff --git a/lib/asn1/test/testChoiceIndefinite.erl b/lib/asn1/test/testChoiceIndefinite.erl
index 5eff4ce5d4..e5f3ee51c8 100644
--- a/lib/asn1/test/testChoiceIndefinite.erl
+++ b/lib/asn1/test/testChoiceIndefinite.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2002-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -22,7 +22,7 @@
-export([compile/3]).
-export([main/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
compile(Config,Rules,Options) ->
diff --git a/lib/asn1/test/testCompactBitString.erl b/lib/asn1/test/testCompactBitString.erl
index 12aae260ea..cd5586602b 100644
--- a/lib/asn1/test/testCompactBitString.erl
+++ b/lib/asn1/test/testCompactBitString.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -23,7 +23,7 @@
-export([compact_bit_string/1, bit_string_unnamed/1,otp_4869/1,
ticket_7734/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
compile(Config,Rules,Option) ->
diff --git a/lib/asn1/test/testConstraints.erl b/lib/asn1/test/testConstraints.erl
index f70089fe82..dcbc04f8d8 100644
--- a/lib/asn1/test/testConstraints.erl
+++ b/lib/asn1/test/testConstraints.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -23,7 +23,7 @@
-export([int_constraints/1,refed_NNL_name/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
diff --git a/lib/asn1/test/testContextSwitchingTypes.erl b/lib/asn1/test/testContextSwitchingTypes.erl
index ef14397d1e..260a016c6c 100644
--- a/lib/asn1/test/testContextSwitchingTypes.erl
+++ b/lib/asn1/test/testContextSwitchingTypes.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -22,7 +22,7 @@
-export([compile/3]).
-export([test/0]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
compile(Config,Rules,Options) ->
@@ -71,13 +71,13 @@ check_EXTERNAL_Idef({Alt,_}) when Alt=='context-negotiation';
ok;
check_EXTERNAL_Idef(I) ->
{error,"failed on identification alternative",I}.
-check_EXTERNAL_DVD(DVD) when list(DVD) ->
+check_EXTERNAL_DVD(DVD) when is_list(DVD) ->
ok;
check_EXTERNAL_DVD(asn1_NOVALUE) ->
ok;
check_EXTERNAL_DVD(DVD) ->
{error,"failed on data-value-descriptor alternative",DVD}.
-check_EXTERNAL_DV(DV) when list(DV) ->
+check_EXTERNAL_DV(DV) when is_list(DV) ->
ok;
check_EXTERNAL_DV(DV) ->
{error,"failed on data-value alternative",DV}.
diff --git a/lib/asn1/test/testDER.erl b/lib/asn1/test/testDER.erl
index 970e8dadd4..630f7ecc14 100644
--- a/lib/asn1/test/testDER.erl
+++ b/lib/asn1/test/testDER.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -22,7 +22,7 @@
-export([compile/3]).
-export([test/0]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
compile(Config,Rule,Options) ->
diff --git a/lib/asn1/test/testDeepTConstr.erl b/lib/asn1/test/testDeepTConstr.erl
index a185a127e5..53d2b3040e 100644
--- a/lib/asn1/test/testDeepTConstr.erl
+++ b/lib/asn1/test/testDeepTConstr.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -23,7 +23,7 @@
-export([compile/3,main/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
compile(Config,Rules,Options) ->
diff --git a/lib/asn1/test/testDef.erl b/lib/asn1/test/testDef.erl
index aa41f7b678..7942a358be 100644
--- a/lib/asn1/test/testDef.erl
+++ b/lib/asn1/test/testDef.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -22,7 +22,7 @@
-export([compile/3]).
-export([main/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-record('Def1',{bool0,
bool1 = asn1_DEFAULT,
diff --git a/lib/asn1/test/testDoubleEllipses.erl b/lib/asn1/test/testDoubleEllipses.erl
index 444b06995f..20be4ea215 100644
--- a/lib/asn1/test/testDoubleEllipses.erl
+++ b/lib/asn1/test/testDoubleEllipses.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2007-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -22,7 +22,7 @@
-export([compile/3]).
-export([main/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-record('Seq',{a, c}).
-record('SeqV2',{a, b ,c}).
diff --git a/lib/asn1/test/testEnumExt.erl b/lib/asn1/test/testEnumExt.erl
index 7e25aa9b4e..4ea0f3b8a1 100644
--- a/lib/asn1/test/testEnumExt.erl
+++ b/lib/asn1/test/testEnumExt.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1998-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -22,7 +22,7 @@
-export([compile/3]).
-export([main/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
compile(Config,Rules,Options) ->
diff --git a/lib/asn1/test/testExternal.erl b/lib/asn1/test/testExternal.erl
index 3c3dc2ea29..6e1fa0ee7d 100644
--- a/lib/asn1/test/testExternal.erl
+++ b/lib/asn1/test/testExternal.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -21,7 +21,7 @@
-export([compile/3]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
compile(Config,Rules,Options) ->
diff --git a/lib/asn1/test/testINSTANCE_OF.erl b/lib/asn1/test/testINSTANCE_OF.erl
index 2a3a5c333b..6ae656da44 100644
--- a/lib/asn1/test/testINSTANCE_OF.erl
+++ b/lib/asn1/test/testINSTANCE_OF.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -21,7 +21,7 @@
-export([compile/3,main/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
compile(Config,Rules,Opt) ->
@@ -73,17 +73,17 @@ test_encdec(_Erule,{lastName,{'GeneralName_lastName',{2,3,4},
test_encdec(Erule,Res) ->
{error,{Erule,Res}}.
-wrap(ber,Int) when list(Int) ->
+wrap(ber,Int) when is_list(Int) ->
binary_to_list(list_to_binary(Int));
-wrap(per,Int) when list(Int) ->
+wrap(per,Int) when is_list(Int) ->
binary_to_list(list_to_binary(Int));
-wrap(ber_bin,Int) when list(Int) ->
+wrap(ber_bin,Int) when is_list(Int) ->
list_to_binary(Int);
-wrap(ber_bin_v2,Int) when list(Int) ->
+wrap(ber_bin_v2,Int) when is_list(Int) ->
list_to_binary(Int);
-wrap(per_bin,Int) when list(Int) ->
+wrap(per_bin,Int) when is_list(Int) ->
list_to_binary(Int);
-wrap(uper_bin,Int) when list(Int) ->
+wrap(uper_bin,Int) when is_list(Int) ->
list_to_binary(Int);
wrap(_,Int) ->
Int.
diff --git a/lib/asn1/test/testInfObj.erl b/lib/asn1/test/testInfObj.erl
index 317cd75e4b..9d73be9f23 100644
--- a/lib/asn1/test/testInfObj.erl
+++ b/lib/asn1/test/testInfObj.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -22,7 +22,7 @@
-export([compile/3,main/1,compile_RANAPfiles/3]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-record('InitiatingMessage',{procedureCode,criticality,value}).
-record('InitiatingMessage2',{procedureCode,criticality,value}).
diff --git a/lib/asn1/test/testInfObjectClass.erl b/lib/asn1/test/testInfObjectClass.erl
index 63b332ad0a..07ebb7dbd0 100644
--- a/lib/asn1/test/testInfObjectClass.erl
+++ b/lib/asn1/test/testInfObjectClass.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -23,7 +23,7 @@
-export([compile/3,main/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
diff --git a/lib/asn1/test/testMegaco.erl b/lib/asn1/test/testMegaco.erl
index 8c0565eec7..ca2b1062d1 100644
--- a/lib/asn1/test/testMegaco.erl
+++ b/lib/asn1/test/testMegaco.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -22,7 +22,7 @@
-export([compile/3,main/2,msg11/0]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-define(MID, {ip4Address, #'IP4Address'{address = [124, 124, 124, 222],
portNumber = 55555}}).
-define(A4444, ["11111111"]).
@@ -163,7 +163,7 @@ read_msg(File) ->
end.
-request(Mid, TransId, ContextId, CmdReq) when list(CmdReq) ->
+request(Mid, TransId, ContextId, CmdReq) when is_list(CmdReq) ->
Actions = [#'ActionRequest'{contextId = ContextId,
commandRequests = CmdReq}],
Req = {transactions,
diff --git a/lib/asn1/test/testMergeCompile.erl b/lib/asn1/test/testMergeCompile.erl
index e70ca16b77..733cbc0eef 100644
--- a/lib/asn1/test/testMergeCompile.erl
+++ b/lib/asn1/test/testMergeCompile.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -22,7 +22,7 @@
-export([compile/3,main/1,mvrasn/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-record('InitiatingMessage',{procedureCode,criticality,value}).
-record('Iu-ReleaseCommand',{protocolIEs,protocolExtensions}).
diff --git a/lib/asn1/test/testMvrasn6.erl b/lib/asn1/test/testMvrasn6.erl
index 65668f3ed4..eaa667e6d7 100644
--- a/lib/asn1/test/testMvrasn6.erl
+++ b/lib/asn1/test/testMvrasn6.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -22,7 +22,7 @@
-export([compile/2]).
-export([main/0]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
compile(Config,Rules) ->
diff --git a/lib/asn1/test/testNBAPsystem.erl b/lib/asn1/test/testNBAPsystem.erl
index 402f16ab5d..1269f94060 100644
--- a/lib/asn1/test/testNBAPsystem.erl
+++ b/lib/asn1/test/testNBAPsystem.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2005-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -21,7 +21,7 @@
-export([compile/3,test/2,cell_setup_req_msg/0]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-record('InitiatingMessage',{
procedureID, criticality, messageDiscriminator, transactionID, value}).
@@ -299,7 +299,7 @@ protocolIEs_051107() ->
compare(V,V) ->
ok;
-compare(V,L) when list(L) ->
+compare(V,L) when is_list(L) ->
compare(V,list_to_binary(L));
compare(_,_) ->
false.
diff --git a/lib/asn1/test/testOpenTypeImplicitTag.erl b/lib/asn1/test/testOpenTypeImplicitTag.erl
index 4300509e07..8662744ed3 100644
--- a/lib/asn1/test/testOpenTypeImplicitTag.erl
+++ b/lib/asn1/test/testOpenTypeImplicitTag.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2002-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -22,7 +22,7 @@
-export([compile/3]).
-export([main/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
compile(Config,Rules,Options) ->
diff --git a/lib/asn1/test/testOpt.erl b/lib/asn1/test/testOpt.erl
index 2967595fd2..a1ad8099b5 100644
--- a/lib/asn1/test/testOpt.erl
+++ b/lib/asn1/test/testOpt.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -22,7 +22,7 @@
-export([compile/2]).
-export([main/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-record('Opt1',{bool0,
bool1 = asn1_NOVALUE,
diff --git a/lib/asn1/test/testParamBasic.erl b/lib/asn1/test/testParamBasic.erl
index 172a2881cd..4ba0029b54 100644
--- a/lib/asn1/test/testParamBasic.erl
+++ b/lib/asn1/test/testParamBasic.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -23,7 +23,7 @@
-export([compile_der/2]).
-export([main/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-record('T11',{number, string=asn1_DEFAULT}).
-record('T12',{number, string=asn1_DEFAULT}).
diff --git a/lib/asn1/test/testParameterizedInfObj.erl b/lib/asn1/test/testParameterizedInfObj.erl
index 91d160f335..b95d627d58 100644
--- a/lib/asn1/test/testParameterizedInfObj.erl
+++ b/lib/asn1/test/testParameterizedInfObj.erl
@@ -22,7 +22,7 @@
-export([compile/3,main/1,ranap/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-record('AllocationOrRetentionPriority',{priorityLevel,iE_Extensions}).
-record('ProtocolExtensionField',{id,criticality,extensionValue}).
diff --git a/lib/asn1/test/testPrim.erl b/lib/asn1/test/testPrim.erl
index 4ccdd82c13..97f99e7b1c 100644
--- a/lib/asn1/test/testPrim.erl
+++ b/lib/asn1/test/testPrim.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -28,7 +28,7 @@
-export([null/1]).
-export([real/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
diff --git a/lib/asn1/test/testPrimExternal.erl b/lib/asn1/test/testPrimExternal.erl
index 2a6384009a..23633177eb 100644
--- a/lib/asn1/test/testPrimExternal.erl
+++ b/lib/asn1/test/testPrimExternal.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -22,7 +22,7 @@
-export([compile/3]).
-export([external/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
compile(Config,Rules,Options) ->
diff --git a/lib/asn1/test/testPrimStrings.erl b/lib/asn1/test/testPrimStrings.erl
index 707ee375c1..33652d6554 100644
--- a/lib/asn1/test/testPrimStrings.erl
+++ b/lib/asn1/test/testPrimStrings.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -31,7 +31,7 @@
-export([times/1]).
-export([utf8_string/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
compile(Config,Rules,Option) ->
@@ -930,7 +930,7 @@ utf8_string(_Rules) ->
?line {ok,Bin13} = asn1_wrapper:decode('PrimStrings','UTF',Bytes13),
?line {ok,LongVal} = wrapper_utf8_binary_to_list(Bin13).
-wrapper_utf8_binary_to_list(L) when list(L) ->
+wrapper_utf8_binary_to_list(L) when is_list(L) ->
asn1rt:utf8_binary_to_list(list_to_binary(L));
wrapper_utf8_binary_to_list(B) ->
asn1rt:utf8_binary_to_list(B).
diff --git a/lib/asn1/test/testRANAP.erl b/lib/asn1/test/testRANAP.erl
index 7c35674d3a..52a58d850b 100644
--- a/lib/asn1/test/testRANAP.erl
+++ b/lib/asn1/test/testRANAP.erl
@@ -22,7 +22,7 @@
-export([compile/3,testobj/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
compile(Config,Erule,Options) ->
diff --git a/lib/asn1/test/testROSE.erl b/lib/asn1/test/testROSE.erl
index 65851e21fc..a692ec7682 100644
--- a/lib/asn1/test/testROSE.erl
+++ b/lib/asn1/test/testROSE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2002-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -21,7 +21,7 @@
-export([compile/3]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
diff --git a/lib/asn1/test/testSSLspecs.erl b/lib/asn1/test/testSSLspecs.erl
index 87e5e5fd02..10623af51e 100644
--- a/lib/asn1/test/testSSLspecs.erl
+++ b/lib/asn1/test/testSSLspecs.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -22,7 +22,7 @@
-export([compile/3,run/1,compile_inline/2,run_inline/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
compile(Config,Rules,Options) ->
diff --git a/lib/asn1/test/testSelectionTypes.erl b/lib/asn1/test/testSelectionTypes.erl
index a3876c259e..893c31622f 100644
--- a/lib/asn1/test/testSelectionTypes.erl
+++ b/lib/asn1/test/testSelectionTypes.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -22,7 +22,7 @@
-export([compile/3]).
-export([test/0]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
compile(Config,Rule,Options) ->
diff --git a/lib/asn1/test/testSeq2738.erl b/lib/asn1/test/testSeq2738.erl
index 0f3c4b7bf7..9cf9c8fcb4 100644
--- a/lib/asn1/test/testSeq2738.erl
+++ b/lib/asn1/test/testSeq2738.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -22,7 +22,7 @@
-export([compile/3]).
-export([main/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
%-record('SeqOpt',{int, opt = asn1_NOVALUE}).
-record('SeqOptFake',{int, opt = asn1_NOVALUE}).
diff --git a/lib/asn1/test/testSeqDefault.erl b/lib/asn1/test/testSeqDefault.erl
index a626bfd645..edf07cf1c1 100644
--- a/lib/asn1/test/testSeqDefault.erl
+++ b/lib/asn1/test/testSeqDefault.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -23,7 +23,7 @@
-export([compile/3]).
-export([main/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-record('SeqDef1',{bool1 = asn1_DEFAULT, int1, seq1 = asn1_DEFAULT}).
-record('SeqDef1Imp',{bool1 = asn1_DEFAULT, int1, seq1 = asn1_DEFAULT}).
diff --git a/lib/asn1/test/testSeqExtension.erl b/lib/asn1/test/testSeqExtension.erl
index 4ddaddb8f1..538e2c250b 100644
--- a/lib/asn1/test/testSeqExtension.erl
+++ b/lib/asn1/test/testSeqExtension.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -23,7 +23,7 @@
-export([compile/3]).
-export([main/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-record('SeqExt1',{}).
-record('SeqExt2',{bool, int}).
diff --git a/lib/asn1/test/testSeqExternal.erl b/lib/asn1/test/testSeqExternal.erl
index f148d32b21..b89b98d3fa 100644
--- a/lib/asn1/test/testSeqExternal.erl
+++ b/lib/asn1/test/testSeqExternal.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -23,7 +23,7 @@
-export([compile/3]).
-export([main/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-record('SeqXSet1',{set, bool, int}).
diff --git a/lib/asn1/test/testSeqIndefinite.erl b/lib/asn1/test/testSeqIndefinite.erl
index b1b622bdfa..9285d7b368 100644
--- a/lib/asn1/test/testSeqIndefinite.erl
+++ b/lib/asn1/test/testSeqIndefinite.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -22,7 +22,7 @@
-export([compile/3]).
-export([main/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
compile(Config,Rules,Options) ->
diff --git a/lib/asn1/test/testSeqOf.erl b/lib/asn1/test/testSeqOf.erl
index 71556ed746..961e2d89d9 100644
--- a/lib/asn1/test/testSeqOf.erl
+++ b/lib/asn1/test/testSeqOf.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -22,7 +22,7 @@
-export([compile/3]).
-export([main/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-record('Seq1',{bool1, int1, seq1 = asn1_DEFAULT}).
-record('Seq2',{seq2 = asn1_DEFAULT, bool2, int2}).
diff --git a/lib/asn1/test/testSeqOfCho.erl b/lib/asn1/test/testSeqOfCho.erl
index eefb258346..05bd45580f 100644
--- a/lib/asn1/test/testSeqOfCho.erl
+++ b/lib/asn1/test/testSeqOfCho.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -22,7 +22,7 @@
-export([compile/3]).
-export([main/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-record('SeqChoDef',{bool1, int1, seq1 = asn1_DEFAULT}).
-record('SeqChoOpt',{bool1, int1, seq1 = asn1_NOVALUE}).
diff --git a/lib/asn1/test/testSeqOfExternal.erl b/lib/asn1/test/testSeqOfExternal.erl
index dde36e6949..4c4c9e2b0f 100644
--- a/lib/asn1/test/testSeqOfExternal.erl
+++ b/lib/asn1/test/testSeqOfExternal.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -23,7 +23,7 @@
-export([compile/3]).
-export([main/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include("External.hrl").
-record('NT',{os, bool}).
diff --git a/lib/asn1/test/testSeqOfIndefinite.erl b/lib/asn1/test/testSeqOfIndefinite.erl
index 8e8967572a..0221581cf1 100644
--- a/lib/asn1/test/testSeqOfIndefinite.erl
+++ b/lib/asn1/test/testSeqOfIndefinite.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -22,7 +22,7 @@
-export([compile/3]).
-export([main/0]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
%-record('Seq1',{bool1, int1, seq1 = asn1_DEFAULT}).
%-record('Seq2',{seq2 = asn1_DEFAULT, bool2, int2}).
diff --git a/lib/asn1/test/testSeqOfTag.erl b/lib/asn1/test/testSeqOfTag.erl
index 0a4e1397a6..4f56ab717b 100644
--- a/lib/asn1/test/testSeqOfTag.erl
+++ b/lib/asn1/test/testSeqOfTag.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -23,7 +23,7 @@
-export([compile/3]).
-export([main/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include("External.hrl").
diff --git a/lib/asn1/test/testSeqOptional.erl b/lib/asn1/test/testSeqOptional.erl
index 7177011427..0125c9fb3e 100644
--- a/lib/asn1/test/testSeqOptional.erl
+++ b/lib/asn1/test/testSeqOptional.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -23,7 +23,7 @@
-export([compile/3]).
-export([main/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-record('SeqOpt1',{bool1 = asn1_NOVALUE, int1, seq1 = asn1_NOVALUE}).
-record('SeqOpt1Imp',{bool1 = asn1_NOVALUE, int1, seq1 = asn1_NOVALUE}).
diff --git a/lib/asn1/test/testSeqPrim.erl b/lib/asn1/test/testSeqPrim.erl
index 7ad1de58a1..ec48d1b779 100644
--- a/lib/asn1/test/testSeqPrim.erl
+++ b/lib/asn1/test/testSeqPrim.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -22,7 +22,7 @@
-export([compile/3]).
-export([main/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-record('Seq',{bool, boolCon, boolPri, boolApp, boolExpCon, boolExpPri, boolExpApp}).
-record('Empty',{}).
diff --git a/lib/asn1/test/testSeqSetDefaultVal.erl b/lib/asn1/test/testSeqSetDefaultVal.erl
index 1c238fd1b7..5a1a443ebc 100644
--- a/lib/asn1/test/testSeqSetDefaultVal.erl
+++ b/lib/asn1/test/testSeqSetDefaultVal.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -23,7 +23,7 @@
-export([compile/2]).
-export([main/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-record('SeqInts',{a = asn1_DEFAULT,
b = asn1_DEFAULT,
diff --git a/lib/asn1/test/testSeqTag.erl b/lib/asn1/test/testSeqTag.erl
index ff6d1bbe91..60d3629840 100644
--- a/lib/asn1/test/testSeqTag.erl
+++ b/lib/asn1/test/testSeqTag.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -22,7 +22,7 @@
-export([compile/3]).
-export([main/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include("External.hrl").
-record('SeqTag',{nt, imp, exp}).
diff --git a/lib/asn1/test/testSeqTypeRefCho.erl b/lib/asn1/test/testSeqTypeRefCho.erl
index 03933d68ae..9262fd1bfd 100644
--- a/lib/asn1/test/testSeqTypeRefCho.erl
+++ b/lib/asn1/test/testSeqTypeRefCho.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -22,7 +22,7 @@
-export([compile/3]).
-export([main/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include("External.hrl").
-record('SeqTRcho',{seqCho, seqChoE, 'seqCho-E', 'seqChoE-E'}).
diff --git a/lib/asn1/test/testSeqTypeRefPrim.erl b/lib/asn1/test/testSeqTypeRefPrim.erl
index 264fc24f85..7d4c2acc0e 100644
--- a/lib/asn1/test/testSeqTypeRefPrim.erl
+++ b/lib/asn1/test/testSeqTypeRefPrim.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -22,7 +22,7 @@
-export([compile/3]).
-export([main/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-record('SeqTR',{octStr, octStrI, octStrE, 'octStr-I', 'octStrI-I', 'octStrE-I', 'octStr-E', 'octStrI-E', 'octStrE-E'}).
diff --git a/lib/asn1/test/testSeqTypeRefSeq.erl b/lib/asn1/test/testSeqTypeRefSeq.erl
index b01c14ee32..51b0f13c57 100644
--- a/lib/asn1/test/testSeqTypeRefSeq.erl
+++ b/lib/asn1/test/testSeqTypeRefSeq.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -22,7 +22,7 @@
-export([compile/3]).
-export([main/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-record('Seq1',{bool1, int1, seq1}).
-record('Seq2',{seq2, bool2, int2}).
diff --git a/lib/asn1/test/testSeqTypeRefSet.erl b/lib/asn1/test/testSeqTypeRefSet.erl
index 92d2cadf28..a704ce3403 100644
--- a/lib/asn1/test/testSeqTypeRefSet.erl
+++ b/lib/asn1/test/testSeqTypeRefSet.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -22,7 +22,7 @@
-export([compile/3]).
-export([main/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-record('SeqTRset',{seqSet, seqSetI, seqSetE, 'seqSet-I', 'seqSetI-I', 'seqSetE-I', 'seqSet-E', 'seqSetI-E', 'seqSetE-E'}).
-record('SeqSet',{setInt, setOs}).
diff --git a/lib/asn1/test/testSetDefault.erl b/lib/asn1/test/testSetDefault.erl
index e4b6a0ab82..e36894327c 100644
--- a/lib/asn1/test/testSetDefault.erl
+++ b/lib/asn1/test/testSetDefault.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -22,7 +22,7 @@
-export([compile/3]).
-export([main/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-record('SetDef1',{bool1 = asn1_DEFAULT, int1, set1 = asn1_DEFAULT}).
-record('SetDef2',{set2 = asn1_DEFAULT, bool2, int2}).
diff --git a/lib/asn1/test/testSetExtension.erl b/lib/asn1/test/testSetExtension.erl
index 85a84e020a..c7fb3b42c4 100644
--- a/lib/asn1/test/testSetExtension.erl
+++ b/lib/asn1/test/testSetExtension.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -24,7 +24,7 @@
-export([compile/3]).
-export([main/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-record('SetExt1',{}).
-record('SetExt2',{bool, int}).
diff --git a/lib/asn1/test/testSetExternal.erl b/lib/asn1/test/testSetExternal.erl
index 83974a5499..41f32dcd90 100644
--- a/lib/asn1/test/testSetExternal.erl
+++ b/lib/asn1/test/testSetExternal.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -23,7 +23,7 @@
-export([compile/3]).
-export([main/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-record('SetXSeq1',{seq, bool, int}).
diff --git a/lib/asn1/test/testSetIndefinite.erl b/lib/asn1/test/testSetIndefinite.erl
index 0e6a86bac4..bf8b242860 100644
--- a/lib/asn1/test/testSetIndefinite.erl
+++ b/lib/asn1/test/testSetIndefinite.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -22,7 +22,7 @@
-export([compile/3]).
-export([main/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
compile(Config,Rules,Options) ->
diff --git a/lib/asn1/test/testSetOf.erl b/lib/asn1/test/testSetOf.erl
index fe68a0705a..0769b9a344 100644
--- a/lib/asn1/test/testSetOf.erl
+++ b/lib/asn1/test/testSetOf.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -22,7 +22,7 @@
-export([compile/3]).
-export([main/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-record('Set1',{bool1, int1, set1 = asn1_DEFAULT}).
-record('Set2',{set2 = asn1_DEFAULT, bool2, int2}).
diff --git a/lib/asn1/test/testSetOfCho.erl b/lib/asn1/test/testSetOfCho.erl
index f3164273f6..474742fbdb 100644
--- a/lib/asn1/test/testSetOfCho.erl
+++ b/lib/asn1/test/testSetOfCho.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -22,7 +22,7 @@
-export([compile/3]).
-export([main/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-record('SetChoDef',{bool1, int1, set1 = asn1_DEFAULT}).
-record('SetChoOpt',{bool1, int1, set1 = asn1_NOVALUE}).
diff --git a/lib/asn1/test/testSetOfExternal.erl b/lib/asn1/test/testSetOfExternal.erl
index 1c59ad0a74..9e2b01c698 100644
--- a/lib/asn1/test/testSetOfExternal.erl
+++ b/lib/asn1/test/testSetOfExternal.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -23,7 +23,7 @@
-export([compile/3]).
-export([main/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include("External.hrl").
-record('NT',{os, bool}).
diff --git a/lib/asn1/test/testSetOfTag.erl b/lib/asn1/test/testSetOfTag.erl
index ff59a329e3..c101306d7a 100644
--- a/lib/asn1/test/testSetOfTag.erl
+++ b/lib/asn1/test/testSetOfTag.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -23,7 +23,7 @@
-export([compile/3]).
-export([main/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include("External.hrl").
diff --git a/lib/asn1/test/testSetOptional.erl b/lib/asn1/test/testSetOptional.erl
index 3df1ed58bb..035fa70424 100644
--- a/lib/asn1/test/testSetOptional.erl
+++ b/lib/asn1/test/testSetOptional.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -23,7 +23,7 @@
-export([compile/3]).
-export([main/1]).
-export([ticket_7533/1,decoder/4]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-record('SetOpt1',{bool1 = asn1_NOVALUE, int1, set1 = asn1_NOVALUE}).
-record('SetOpt1Imp',{bool1 = asn1_NOVALUE, int1, set1 = asn1_NOVALUE}).
diff --git a/lib/asn1/test/testSetPrim.erl b/lib/asn1/test/testSetPrim.erl
index cb64011dcc..e093c918e3 100644
--- a/lib/asn1/test/testSetPrim.erl
+++ b/lib/asn1/test/testSetPrim.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -22,7 +22,7 @@
-export([compile/3]).
-export([main/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-record('Set',{bool, boolCon, boolPri, boolApp, boolExpCon, boolExpPri, boolExpApp}).
-record('Empty',{}).
diff --git a/lib/asn1/test/testSetTag.erl b/lib/asn1/test/testSetTag.erl
index fcf15dc0f0..8df3e36815 100644
--- a/lib/asn1/test/testSetTag.erl
+++ b/lib/asn1/test/testSetTag.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -22,7 +22,7 @@
-export([compile/3]).
-export([main/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include("External.hrl").
-record('SetTag',{nt, imp, exp}).
diff --git a/lib/asn1/test/testSetTypeRefCho.erl b/lib/asn1/test/testSetTypeRefCho.erl
index c2dbf076bd..1f68a8fbc4 100644
--- a/lib/asn1/test/testSetTypeRefCho.erl
+++ b/lib/asn1/test/testSetTypeRefCho.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -22,7 +22,7 @@
-export([compile/3]).
-export([main/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-include("External.hrl").
-record('SetTRcho',{setCho, setChoE, 'setCho-E', 'setChoE-E'}).
diff --git a/lib/asn1/test/testSetTypeRefPrim.erl b/lib/asn1/test/testSetTypeRefPrim.erl
index 1f95947168..e6cec260e5 100644
--- a/lib/asn1/test/testSetTypeRefPrim.erl
+++ b/lib/asn1/test/testSetTypeRefPrim.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -22,7 +22,7 @@
-export([compile/3]).
-export([main/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-record('SetTR',{octStr, octStrI, octStrE, 'octStr-I', 'octStrI-I', 'octStrE-I', 'octStr-E', 'octStrI-E', 'octStrE-E'}).
diff --git a/lib/asn1/test/testSetTypeRefSeq.erl b/lib/asn1/test/testSetTypeRefSeq.erl
index 2f6dfec9c6..0c1c9400bf 100644
--- a/lib/asn1/test/testSetTypeRefSeq.erl
+++ b/lib/asn1/test/testSetTypeRefSeq.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -22,7 +22,7 @@
-export([compile/3]).
-export([main/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-record('SetTRseq',{setSeq, setSeqI, setSeqE, 'setSeq-I', 'setSeqI-I', 'setSeqE-I', 'setSeq-E', 'setSeqI-E', 'setSeqE-E'}).
-record('SetSeq',{seqInt, seqOs}).
diff --git a/lib/asn1/test/testSetTypeRefSet.erl b/lib/asn1/test/testSetTypeRefSet.erl
index 132e5fb3f5..6544e77458 100644
--- a/lib/asn1/test/testSetTypeRefSet.erl
+++ b/lib/asn1/test/testSetTypeRefSet.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -22,7 +22,7 @@
-export([compile/3]).
-export([main/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-record('Set1',{bool1, int1, set1}).
-record('Set2',{set2, bool2, int2}).
diff --git a/lib/asn1/test/testTCAP.erl b/lib/asn1/test/testTCAP.erl
index 3e2c2de371..5e29938a16 100644
--- a/lib/asn1/test/testTCAP.erl
+++ b/lib/asn1/test/testTCAP.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -21,7 +21,7 @@
-export([compile/3,test/2,compile_asn1config/3,test_asn1config/0]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
diff --git a/lib/asn1/test/testTcapsystem.erl b/lib/asn1/test/testTcapsystem.erl
index c48b1b835d..2f13c11cd4 100644
--- a/lib/asn1/test/testTcapsystem.erl
+++ b/lib/asn1/test/testTcapsystem.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -21,7 +21,7 @@
-export([compile/3]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
diff --git a/lib/asn1/test/testTimer.erl b/lib/asn1/test/testTimer.erl
index 0fade7ebca..74002e16e9 100644
--- a/lib/asn1/test/testTimer.erl
+++ b/lib/asn1/test/testTimer.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2001-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -22,7 +22,7 @@
-compile(export_all).
%%-export([Function/Arity, ...]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-define(times, 5000).
@@ -146,7 +146,7 @@ go(Config,Enc) ->
Bytes = case Enc of
ber_bin ->
list_to_binary(B);
- per_bin when list(B) ->
+ per_bin when is_list(B) ->
list_to_binary(B);
per_bin ->
B;
@@ -179,7 +179,7 @@ encode(0, _Module,_Type,_Value) ->
encode(N, Module,Type,Value) ->
?line {ok,B} = asn1rt:encode(Module,Type,Value),
_B2 = if
- list(B) -> list_to_binary(B);
+ is_list(B) -> list_to_binary(B);
true -> B
end,
encode(N-1, Module,Type,Value).
diff --git a/lib/asn1/test/testTypeValueNotation.erl b/lib/asn1/test/testTypeValueNotation.erl
index 0fc3dc3197..f0699370e0 100644
--- a/lib/asn1/test/testTypeValueNotation.erl
+++ b/lib/asn1/test/testTypeValueNotation.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2002-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -22,7 +22,7 @@
-export([compile/3]).
-export([main/2]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-record('Seq',{octstr, int, bool, enum, bitstr, null, oid, vstr}).
diff --git a/lib/asn1/test/testX420.erl b/lib/asn1/test/testX420.erl
index 0fa3e6fb13..1d18e76c48 100644
--- a/lib/asn1/test/testX420.erl
+++ b/lib/asn1/test/testX420.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -23,7 +23,7 @@
-export([compile/3, ticket7759/2]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
compile(Erule,Options,Config) ->
@@ -50,7 +50,7 @@ compile_loop(Erule,[Spec|Specs],Options,Config)
Error ->
Error
end;
-compile_loop(Erule,_Specs,_Options,_Config) ->
+compile_loop(_Erule,_Specs,_Options,_Config) ->
ok.%%{skip,io_lib:format("Not tested for ~p",[Erule])}.
diff --git a/lib/asn1/test/test_bad_values.erl b/lib/asn1/test/test_bad_values.erl
index 0190b6ee9a..d379a509ab 100644
--- a/lib/asn1/test/test_bad_values.erl
+++ b/lib/asn1/test/test_bad_values.erl
@@ -1,26 +1,26 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2005-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
-module(test_bad_values).
-export([tests/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
tests(Config) ->
?line DataDir = ?config(data_dir,Config),
diff --git a/lib/asn1/test/test_compile_options.erl b/lib/asn1/test/test_compile_options.erl
index a6e0caa0f1..d51b2a6c4a 100644
--- a/lib/asn1/test/test_compile_options.erl
+++ b/lib/asn1/test/test_compile_options.erl
@@ -1,26 +1,26 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2005-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
-module(test_compile_options).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-export([wrong_path/1,comp/2,path/1,ticket_6143/1,noobj/1,
diff --git a/lib/asn1/test/test_driver_load.erl b/lib/asn1/test/test_driver_load.erl
index 37a7e36a45..965f2473e9 100644
--- a/lib/asn1/test/test_driver_load.erl
+++ b/lib/asn1/test/test_driver_load.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -21,7 +21,7 @@
-export([compile/2,test/2,encode/0]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
test(per_bin,0) ->
diff --git a/lib/asn1/test/test_inline.erl b/lib/asn1/test/test_inline.erl
index aac003baf6..dfa3c134ae 100644
--- a/lib/asn1/test/test_inline.erl
+++ b/lib/asn1/test/test_inline.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -23,7 +23,7 @@
-export([mvrasn_inlined_encdec/2,mvrasn_encdec/2,
mi_encdec/2,m_encdec/2]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
-define(times, 5000).
-define(times2, 50000).
diff --git a/lib/asn1/test/test_modified_x420.erl b/lib/asn1/test/test_modified_x420.erl
index 93fcd73eaf..4e96db070b 100644
--- a/lib/asn1/test/test_modified_x420.erl
+++ b/lib/asn1/test/test_modified_x420.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -22,7 +22,7 @@
%-compile(export_all).
-export([compile/1, test_io/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
compile(Config) ->
?line DataDir = ?config(data_dir,Config),
diff --git a/lib/asn1/test/test_partial_incomplete_decode.erl b/lib/asn1/test/test_partial_incomplete_decode.erl
index 9fd078e952..a2e0a96bd8 100644
--- a/lib/asn1/test/test_partial_incomplete_decode.erl
+++ b/lib/asn1/test/test_partial_incomplete_decode.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -21,7 +21,7 @@
-export([compile/3,test/2]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
diff --git a/lib/asn1/test/test_selective_decode.erl b/lib/asn1/test/test_selective_decode.erl
index 94d3d5f34a..e1e101b622 100644
--- a/lib/asn1/test/test_selective_decode.erl
+++ b/lib/asn1/test/test_selective_decode.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -21,7 +21,7 @@
-export([test/2]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
test(ber_bin_v2,_Config) ->
diff --git a/lib/asn1/test/test_special_decode_performance.erl b/lib/asn1/test/test_special_decode_performance.erl
index c451d65172..60a95a3675 100644
--- a/lib/asn1/test/test_special_decode_performance.erl
+++ b/lib/asn1/test/test_special_decode_performance.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2003-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -21,7 +21,7 @@
-export([compile/2,go/1,loop2/4,loop1/5]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
compile(Config,Rule) when Rule==ber_bin_v2 ->
diff --git a/lib/asn1/test/test_undecoded_rest.erl b/lib/asn1/test/test_undecoded_rest.erl
index c7762d28f7..647fe2bb1c 100644
--- a/lib/asn1/test/test_undecoded_rest.erl
+++ b/lib/asn1/test/test_undecoded_rest.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -21,7 +21,7 @@
-export([compile/3,test/1]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
%% testing OTP-5104
@@ -39,10 +39,10 @@ test(Opt) ->
?line {ok,Msg} = asn1ct:value('P-Record','PersonnelRecord'),
?line {ok,Bytes} = asn1_wrapper:encode('P-Record','PersonnelRecord',Msg),
Bytes2 =
- fun(B) when list(B) ->
+ fun(B) when is_list(B) ->
B ++ [55,55,55];
- (B) when binary(B) ->
- concat_binary([B,<<55,55,55>>])
+ (B) when is_binary(B) ->
+ iolist_to_binary([B,<<55,55,55>>])
end (Bytes),
case Opt of
diff --git a/lib/asn1/test/test_x691.erl b/lib/asn1/test/test_x691.erl
index 5bf3a4a077..bc8a3495d8 100644
--- a/lib/asn1/test/test_x691.erl
+++ b/lib/asn1/test/test_x691.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -22,7 +22,7 @@
-export([compile/3]).
-export([cases/2]).
--include("test_server.hrl").
+-include_lib("test_server/include/test_server.hrl").
compile(Config,Rules,Option) ->
diff --git a/lib/compiler/src/v3_life.erl b/lib/compiler/src/v3_life.erl
index 0adeaca8fa..8e6b153d57 100644
--- a/lib/compiler/src/v3_life.erl
+++ b/lib/compiler/src/v3_life.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%% Purpose : Convert annotated kernel expressions to annotated beam format.
@@ -66,21 +66,27 @@ functions([], Acc) -> reverse(Acc).
%% function(Kfunc) -> Func.
function(#k_fdef{func=F,arity=Ar,vars=Vs,body=Kb}) ->
- %ok = io:fwrite("life ~w: ~p~n~p~n", [?LINE,{F,Ar},Kb]),
- As = var_list(Vs),
- Vdb0 = foldl(fun ({var,N}, Vdb) -> new_var(N, 0, Vdb) end, [], As),
- %% Force a top-level match!
- B0 = case Kb of
- #k_match{} -> Kb;
- _ ->
- Ka = get_kanno(Kb),
- #k_match{anno=#k{us=Ka#k.us,ns=[],a=Ka#k.a},
- vars=Vs,body=Kb,ret=[]}
- end,
- put(guard_refc, 0),
- {B1,_,Vdb1} = body(B0, 1, Vdb0),
- erase(guard_refc),
- {function,F,Ar,As,B1,Vdb1}.
+ try
+ As = var_list(Vs),
+ Vdb0 = foldl(fun ({var,N}, Vdb) -> new_var(N, 0, Vdb) end, [], As),
+ %% Force a top-level match!
+ B0 = case Kb of
+ #k_match{} -> Kb;
+ _ ->
+ Ka = get_kanno(Kb),
+ #k_match{anno=#k{us=Ka#k.us,ns=[],a=Ka#k.a},
+ vars=Vs,body=Kb,ret=[]}
+ end,
+ put(guard_refc, 0),
+ {B1,_,Vdb1} = body(B0, 1, Vdb0),
+ erase(guard_refc),
+ {function,F,Ar,As,B1,Vdb1}
+ catch
+ Class:Error ->
+ Stack = erlang:get_stacktrace(),
+ io:fwrite("Function: ~w/~w\n", [F,Ar]),
+ erlang:raise(Class, Error, Stack)
+ end.
%% body(Kbody, I, Vdb) -> {[Expr],MaxI,Vdb}.
%% Handle a body, need special cases for transforming match_fails.
diff --git a/lib/cosTransactions/doc/src/ch_example.xml b/lib/cosTransactions/doc/src/ch_example.xml
index 65350166f0..026bfc467e 100644
--- a/lib/cosTransactions/doc/src/ch_example.xml
+++ b/lib/cosTransactions/doc/src/ch_example.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1999</year><year>2009</year>
+ <year>1999</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>cosTransactions Examples</title>
@@ -83,7 +83,9 @@ module ownResourceImpl {
<item><c>commit_one_phase/1</c> - if possible, the Resource should commit all changes made as part of the transaction.
This operation can only be used if the Resource is the only child of its parent. </item>
<item><c>forget/1</c> - this operation informs the Resource that it is safe to forget any
- <term id="Heuristic decisions"><termdef>Heuristic decisions is a unilateral decision by a participant to commit or rollback without receiving the true outcome of the transaction from its parents coordinator.</termdef></term>and the knowledge of the transaction.</item>
+ <term id="Heuristic decisions"><termdef>Heuristic decisions is a unilateral decision by a participant to commit
+ or rollback without receiving the true outcome of the transaction from its parent's coordinator.</termdef></term>
+ and the knowledge of the transaction.</item>
<item><c>ownFunctions</c> - all application specific operations.</item>
</list>
<p>If the participant wants to be notified when a subtransaction commits, we must also implement the following operations
diff --git a/lib/erl_interface/doc/src/ei.xml b/lib/erl_interface/doc/src/ei.xml
index 2f65a8c375..9083ae02b0 100644
--- a/lib/erl_interface/doc/src/ei.xml
+++ b/lib/erl_interface/doc/src/ei.xml
@@ -4,7 +4,7 @@
<cref>
<header>
<copyright>
- <year>2001</year><year>2009</year>
+ <year>2001</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>ei</title>
@@ -333,7 +333,7 @@ ei_encode_tuple_header(buf, &amp;i, 0);
<desc>
<p>This function encodes a list header, with a specified
arity. The next <c><![CDATA[arity+1]]></c> terms are the elements
- (actually it's <c><![CDATA[arity]]></c> cons cells) and the tail of the
+ (actually its <c><![CDATA[arity]]></c> cons cells) and the tail of the
list. Lists and tuples are encoded recursively, so that a
list may contain another list or tuple.</p>
<p>E.g. to encode the list <c><![CDATA[[c, d, [e | f]]]]></c>:</p>
diff --git a/lib/erl_interface/doc/src/erl_call.xml b/lib/erl_interface/doc/src/erl_call.xml
index 2d88e7616a..c597e11481 100644
--- a/lib/erl_interface/doc/src/erl_call.xml
+++ b/lib/erl_interface/doc/src/erl_call.xml
@@ -4,7 +4,7 @@
<comref>
<header>
<copyright>
- <year>1996</year><year>2009</year>
+ <year>1996</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>erl_call</title>
@@ -61,7 +61,7 @@
<item>
<p>(<em>optional</em>): Applies the specified function
and returns the result. <c><![CDATA[Mod]]></c> must be specified, however
- <em>[]</em> is assumed for unspecified <c><![CDATA[Fun]]></c> and <c><![CDATA[Args]]></c>. <c><![CDATA[Args]]></c> should
+ <c>start</c> and <c>[]</c> are assumed for unspecified <c><![CDATA[Fun]]></c> and <c><![CDATA[Args]]></c>, respectively. <c><![CDATA[Args]]></c> should
be in the same format as for <c><![CDATA[erlang:apply/3]]></c>. Note
that this flag takes exactly one argument, so quoting
may be necessary in order to group <c><![CDATA[Mod]]></c>, <c><![CDATA[Fun]]></c>
diff --git a/lib/hipe/cerl/erl_bif_types.erl b/lib/hipe/cerl/erl_bif_types.erl
index 38342870e5..81ca837e45 100644
--- a/lib/hipe/cerl/erl_bif_types.erl
+++ b/lib/hipe/cerl/erl_bif_types.erl
@@ -4534,7 +4534,7 @@ t_decode_packet_option() ->
t_tuple([t_atom('line_length'), t_non_neg_integer()])]).
t_decode_packet_type() ->
- t_sup(t_inet_setoption_packettype(), t_atom('httph')).
+ t_sup([t_inet_setoption_packettype(), t_atom('httph'), t_atom('httph_bin')]).
t_dist_exit() ->
t_sup([t_atom('kill'), t_atom('noconnection'), t_atom('normal')]).
diff --git a/lib/ic/doc/src/ch_c_mapping.xml b/lib/ic/doc/src/ch_c_mapping.xml
index f5a921bfd2..23a9361c2c 100644
--- a/lib/ic/doc/src/ch_c_mapping.xml
+++ b/lib/ic/doc/src/ch_c_mapping.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1998</year><year>2009</year>
+ <year>1998</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>IDL to C mapping</title>
@@ -804,7 +804,7 @@ CORBA_Environment* oe_env)
octets</p>
</item>
</list>
- <p>The erlang binary IDL type is defined in <c>erlang.idl</c>, while it's
+ <p>The erlang binary IDL type is defined in <c>erlang.idl</c>, while its
C definition is located in the <c>ic.h</c> header file, both in the
<c><![CDATA[IC-< vsn >/include]]></c> directory.
The user will have to include the file <c>erlang.idl</c> in order to use the
diff --git a/lib/inets/doc/src/http_server.xml b/lib/inets/doc/src/http_server.xml
index 547617e2e3..01e0b47d37 100644
--- a/lib/inets/doc/src/http_server.xml
+++ b/lib/inets/doc/src/http_server.xml
@@ -357,7 +357,7 @@ UserName:Password
<p>The mod_cgi module makes it possible to execute CGI scripts
in the server. A file that matches the definition of a
ScriptAlias config directive is treated as a CGI script. A CGI
- script is executed by the server and it's output is returned to
+ script is executed by the server and its output is returned to
the client. </p>
<p>The CGI Script response comprises a message-header and a
message-body, separated by a blank line. The message-header
diff --git a/lib/inets/doc/src/httpc.xml b/lib/inets/doc/src/httpc.xml
index ca93190f61..7430a62b1b 100644
--- a/lib/inets/doc/src/httpc.xml
+++ b/lib/inets/doc/src/httpc.xml
@@ -191,7 +191,8 @@ ssl_options() = {verify, code()} |
<v>Result = {status_line(), headers(), body()} |
{status_code(), body()} | request_id() </v>
<v>Profile = profile() </v>
- <v>Reason = term() </v>
+ <v>Reason = {connect_failed, term()} |
+ {send_failed, term()} | term() </v>
</type>
<desc>
diff --git a/lib/inets/doc/src/httpd_util.xml b/lib/inets/doc/src/httpd_util.xml
index 642e5213b0..6ac2b13c72 100644
--- a/lib/inets/doc/src/httpd_util.xml
+++ b/lib/inets/doc/src/httpd_util.xml
@@ -63,7 +63,7 @@
<v>Etag = string()</v>
</type>
<desc>
- <p><c>create_etag/1</c> calculates the Etag for a file, from it's
+ <p><c>create_etag/1</c> calculates the Etag for a file, from its
size and time for last modification. fileinfo is a record defined
in <c>kernel/include/file.hrl</c></p>
@@ -78,7 +78,7 @@
<v>HexValue = DecValue = string()</v>
</type>
<desc>
- <p>Converts the hexadecimal value <c>HexValue</c> into it's
+ <p>Converts the hexadecimal value <c>HexValue</c> into its
decimal equivalent (<c>DecValue</c>).</p>
<marker id="day"></marker>
diff --git a/lib/inets/doc/src/mod_security.xml b/lib/inets/doc/src/mod_security.xml
index 5f9f88071e..2a871d29d8 100644
--- a/lib/inets/doc/src/mod_security.xml
+++ b/lib/inets/doc/src/mod_security.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1998</year><year>2009</year>
+ <year>1998</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>mod_security</title>
@@ -117,11 +117,14 @@
<section>
<marker id="callback_module"></marker>
<title>The SecurityCallbackModule</title>
- <p>The SecurityCallbackModule is a user written module that can receive events from
- the mod_security Erlang Webserver API module. This module only exports one function,
- <seealso marker="#callback_module_event">event/4</seealso>, which is described below.
+ <p>The SecurityCallbackModule is a user written module that can receive
+ events from the mod_security Erlang Webserver API module.
+ This module only exports the function(s),
+ <seealso marker="#callback_module_event">event/4,5</seealso>,
+ which are described below.
</p>
</section>
+
<funcs>
<func>
<name>event(What, Port, Dir, Data) -> ignored</name>
@@ -131,7 +134,7 @@
<v>What = atom()</v>
<v>Port = integer()</v>
<v>Address = {A,B,C,D} | string() &lt;v>Dir = string()</v>
- <v>What = [Info]</v>
+ <v>Data = [Info]</v>
<v>Info = {Name, Value}</v>
</type>
<desc>
diff --git a/lib/inets/doc/src/notes.xml b/lib/inets/doc/src/notes.xml
index 0c524f00d1..762c2c84c5 100644
--- a/lib/inets/doc/src/notes.xml
+++ b/lib/inets/doc/src/notes.xml
@@ -32,6 +32,70 @@
<file>notes.xml</file>
</header>
+ <section><title>Inets 5.3.1</title>
+
+ <section><title>Improvements and New Features</title>
+ <p>-</p>
+
+<!--
+ <list>
+ <item>
+ <p>[httpc] - Allow users to pass socket options to the transport
+ module when making requests. </p>
+ <p>See the <c>socket_opts</c> option in the
+ <seealso marker="httpc#request2">request/4</seealso> or
+ <seealso marker="httpc#set_options">set_options/1,2</seealso>
+ for more info, </p>
+ <p>Own Id: OTP-8352</p>
+ </item>
+
+ </list>
+-->
+ </section>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+
+<!--
+ <p>-</p>
+-->
+
+ <list>
+ <item>
+ <p>[httpc] - Badly formated error reason for errors occuring
+ during initial connect to a server.
+ Also, the possible error reasons was
+ not properly documented.</p>
+ <p>Own Id: OTP-8508</p>
+ <p>Aux Id: seq11407</p>
+ </item>
+
+ <item>
+ <p>[httpd] - Issues with ESI erl_script_timeout. </p>
+ <p>
+ <list type="bulleted">
+ <item>
+ <p>The <c>erl_script_timeout</c> config option is ducumented
+ as a number of seconds. But when parsing the config, in the
+ new format (not a config file), it was handled as if in
+ number of milliseconds. </p>
+ </item>
+ <item>
+ <p>When the erl-script-timeout time was exceeded, the server
+ incorrectly marked the answer as sent, thereby leaving
+ client hanging (with an incomplete answer).
+ This has been changed, so that now the socket will be
+ closed. </p>
+ </item>
+ </list>
+ </p>
+ <p>Own Id: OTP-8509</p>
+ </item>
+ </list>
+ </section>
+
+ </section> <!-- 5.3.1 -->
+
+
<section><title>Inets 5.3</title>
<section><title>Improvements and New Features</title>
diff --git a/lib/inets/src/http_client/httpc_handler.erl b/lib/inets/src/http_client/httpc_handler.erl
index 31585537d4..695ff9cf82 100644
--- a/lib/inets/src/http_client/httpc_handler.erl
+++ b/lib/inets/src/http_client/httpc_handler.erl
@@ -280,7 +280,7 @@ handle_call({connect_and_send, #request{address = Address0,
{ok, NewState} ->
{reply, ok, NewState};
{stop, Error, NewState} ->
- {stop, Error, Error, NewState}
+ {stop, normal, Error, NewState}
end
end;
@@ -675,6 +675,24 @@ handle_info({'EXIT', _, _}, State) ->
%%--------------------------------------------------------------------
%% Init error there is no socket to be closed.
+terminate(normal,
+ #state{request = Request,
+ session = {send_failed, AReason} = Reason} = State) ->
+ ?hcrd("terminate", [{send_reason, AReason}, {request, Request}]),
+ maybe_send_answer(Request,
+ httpc_response:error(Request, Reason),
+ State),
+ ok;
+
+terminate(normal,
+ #state{request = Request,
+ session = {connect_failed, AReason} = Reason} = State) ->
+ ?hcrd("terminate", [{connect_reason, AReason}, {request, Request}]),
+ maybe_send_answer(Request,
+ httpc_response:error(Request, Reason),
+ State),
+ ok;
+
terminate(normal, #state{session = undefined}) ->
ok;
@@ -886,18 +904,17 @@ connect_and_send_first_request(Address,
NewState = activate_request_timeout(TmpState),
{ok, NewState};
- {error, Reason} ->
+ {error, Reason} = Error ->
?hcrv("failed sending request", [{reason, Reason}]),
- Error = {error, {send_failed,
- httpc_response:error(Request, Reason)}},
- {stop, Error, State#state{request = Request}}
+ {stop, Error,
+ State#state{session = {send_failed, Reason},
+ request = Request}}
end;
- {error, Reason} ->
+ {error, Reason} = Error ->
?hcri("connect failed", [{reason, Reason}]),
- Error = {error, {connect_failed,
- httpc_response:error(Request, Reason)}},
- {stop, Error, State#state{request = Request}}
+ {stop, Error, State#state{session = {connect_failed, Reason},
+ request = Request}}
end.
diff --git a/lib/inets/src/http_server/httpd_conf.erl b/lib/inets/src/http_server/httpd_conf.erl
index 3e498d1db7..5ca2e47eb5 100644
--- a/lib/inets/src/http_server/httpd_conf.erl
+++ b/lib/inets/src/http_server/httpd_conf.erl
@@ -354,7 +354,7 @@ load("DocumentRoot " ++ DocumentRoot,[]) ->
{ok, Directory} ->
{ok, [], {document_root,string:strip(Directory,right,$/)}};
{error, _} ->
- {error, ?NICE(clean(DocumentRoot)++"is an invalid DocumentRoot")}
+ {error, ?NICE(clean(DocumentRoot)++" is an invalid DocumentRoot")}
end;
load("DefaultType " ++ DefaultType, []) ->
{ok, [], {default_type,clean(DefaultType)}};
diff --git a/lib/inets/src/http_server/mod_esi.erl b/lib/inets/src/http_server/mod_esi.erl
index 484d4b3fb4..cb33544540 100644
--- a/lib/inets/src/http_server/mod_esi.erl
+++ b/lib/inets/src/http_server/mod_esi.erl
@@ -33,6 +33,7 @@
-define(VMODULE,"ESI").
-define(DEFAULT_ERL_TIMEOUT,15000).
+
%%%=========================================================================
%%% API
%%%=========================================================================
@@ -52,6 +53,7 @@ deliver(SessionID, Data) when is_pid(SessionID) ->
deliver(_SessionID, _Data) ->
{error, bad_sessionID}.
+
%%%=========================================================================
%%% CALLBACK API
%%%=========================================================================
@@ -74,6 +76,8 @@ do(ModData) ->
{proceed, ModData#mod.data}
end
end.
+
+
%%--------------------------------------------------------------------------
%% load(Line, Context) -> eof | ok | {ok, NewContext} |
%% {ok, NewContext, Directive} |
@@ -127,6 +131,7 @@ load("ErlScriptNoCache " ++ CacheArg, [])->
" is an invalid ErlScriptNoCache directive")}
end.
+
%%--------------------------------------------------------------------------
%% store(Directive, DirectiveList) -> {ok, NewDirective} |
%% {ok, [NewDirective]} |
@@ -163,16 +168,18 @@ store({eval_script_alias, {Name, Modules}} = Conf, _)
store({erl_script_alias, Value}, _) ->
{error, {wrong_type, {erl_script_alias, Value}}};
-store({erl_script_timeout, Value} = Conf, _)
- when is_integer(Value), Value >= 0 ->
- {ok, Conf};
+store({erl_script_timeout, TimeoutSec}, _)
+ when is_integer(TimeoutSec) andalso (TimeoutSec >= 0) ->
+ {ok, {erl_script_timeout, TimeoutSec * 1000}};
store({erl_script_timeout, Value}, _) ->
{error, {wrong_type, {erl_script_timeout, Value}}};
-store({erl_script_nocache, Value} = Conf, _) when Value == true;
- Value == false ->
+store({erl_script_nocache, Value} = Conf, _)
+ when (Value =:= true) orelse (Value =:= false) ->
{ok, Conf};
store({erl_script_nocache, Value}, _) ->
{error, {wrong_type, {erl_script_nocache, Value}}}.
+
+
%%%========================================================================
%%% Internal functions
%%%========================================================================
@@ -227,7 +234,7 @@ alias_match_str(Alias, eval_script_alias) ->
%%------------------------ Erl mechanism --------------------------------
erl(#mod{method = Method} = ModData, ESIBody, Modules)
- when Method == "GET"; Method == "HEAD"->
+ when (Method =:= "GET") orelse (Method =:= "HEAD") ->
case httpd_util:split(ESIBody,":|%3A|/",2) of
{ok, [ModuleName, FuncAndInput]} ->
case httpd_util:split(FuncAndInput,"[\?/]",2) of
@@ -347,7 +354,7 @@ erl_scheme_webpage_chunk(Mod, Func, Env, Input, ModData) ->
Pid = spawn_link(
fun() ->
case catch Mod:Func(Self, Env, Input) of
- {'EXIT',{undef,_}} ->
+ {'EXIT', {undef,_}} ->
%% Will force fallback on the old API
exit(erl_scheme_webpage_chunk_undefined);
_ ->
@@ -430,11 +437,12 @@ handle_body(Pid, ModData, Body, Timeout, Size, IsDisableChunkedSend) ->
{proceed, [{response, {already_sent, 200, Size}} |
ModData#mod.data]};
{'EXIT', Pid, Reason} when is_pid(Pid) ->
+ httpd_response:send_final_chunk(ModData, IsDisableChunkedSend),
exit({mod_esi_linked_process_died, Pid, Reason})
after Timeout ->
process_flag(trap_exit,false),
- {proceed,[{response, {already_sent, 200, Size}} |
- ModData#mod.data]}
+ httpd_response:send_final_chunk(ModData, IsDisableChunkedSend),
+ exit({mod_esi_linked_process_timeout, Pid})
end.
erl_script_timeout(Db) ->
diff --git a/lib/inets/src/inets_app/inets.appup.src b/lib/inets/src/inets_app/inets.appup.src
index 2efa7ccb60..ba1dc8ccdb 100644
--- a/lib/inets/src/inets_app/inets.appup.src
+++ b/lib/inets/src/inets_app/inets.appup.src
@@ -18,6 +18,12 @@
{"%VSN%",
[
+ {"5.3",
+ [
+ {update, httpc_handler, soft, soft_purge, soft_purge, [mod_esi]},
+ {load_module, mod_esi, soft_purge, soft_purge, []}
+ ]
+ },
{"5.2",
[
{restart_application, inets}
@@ -35,6 +41,12 @@
}
],
[
+ {"5.3",
+ [
+ {update, httpc_handler, soft, soft_purge, soft_purge, [mod_esi]},
+ {load_module, mod_esi, soft_purge, soft_purge, []}
+ ]
+ },
{"5.2",
[
{restart_application, inets}
diff --git a/lib/inets/vsn.mk b/lib/inets/vsn.mk
index 23de8906e7..401bf4d37d 100644
--- a/lib/inets/vsn.mk
+++ b/lib/inets/vsn.mk
@@ -18,11 +18,13 @@
# %CopyrightEnd%
APPLICATION = inets
-INETS_VSN = 5.3
+INETS_VSN = 5.3.1
PRE_VSN =
APP_VSN = "$(APPLICATION)-$(INETS_VSN)$(PRE_VSN)"
-TICKETS = \
+TICKETS = OTP-8508 OTP-8509
+
+TICKETS_5_3 = \
OTP-8016 \
OTP-8056 \
OTP-8103 \
diff --git a/lib/kernel/doc/src/application.xml b/lib/kernel/doc/src/application.xml
index 08ef0b1e52..47d578a339 100644
--- a/lib/kernel/doc/src/application.xml
+++ b/lib/kernel/doc/src/application.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2009</year>
+ <year>1996</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>application</title>
@@ -503,7 +503,7 @@ Nodes = [cp1@cave, {cp2@cave, cp3@cave}]</code>
the tree.</p>
<p><c>StartType</c> defines the type of start:</p>
<list type="bulleted">
- <item><c>normal</c> if its a normal startup.</item>
+ <item><c>normal</c> if it's a normal startup.</item>
<item><c>normal</c> also if the application is distributed and
started at the current node due to a failover from another
node, and the application specification key <c>start_phases == undefined</c>.</item>
diff --git a/lib/kernel/doc/src/erl_ddll.xml b/lib/kernel/doc/src/erl_ddll.xml
index 75dca8a85d..4e65bf46f8 100644
--- a/lib/kernel/doc/src/erl_ddll.xml
+++ b/lib/kernel/doc/src/erl_ddll.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1997</year><year>2009</year>
+ <year>1997</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>erl_ddll</title>
@@ -730,7 +730,7 @@
extension suffix, i.e. <c>.so</c>). The name by which
the driver identifies itself must also be consistent
with this <c>Name</c> parameter, much as a beam-file's
- module name much correspond to it's filename.</p>
+ module name much correspond to its filename.</p>
</item>
<tag><em>OptionList</em></tag>
<item>
@@ -742,8 +742,8 @@
<tag><em>{driver_options, DriverOptionsList}</em></tag>
<item>
<p>This option is to provide options that will change
- it's general behavior and will "stick" to the driver
- throughout it's lifespan.</p>
+ its general behavior and will "stick" to the driver
+ throughout its lifespan.</p>
<p>The driver options for a given driver name need
always to be consistent, <em>even when the driver is reloaded</em>, meaning that they are as much a part
of the driver as the actual name.</p>
diff --git a/lib/kernel/doc/src/file.xml b/lib/kernel/doc/src/file.xml
index f9f5443f68..50f9722a1c 100644
--- a/lib/kernel/doc/src/file.xml
+++ b/lib/kernel/doc/src/file.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>1996</year><year>2009</year>
+ <year>1996</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>file</title>
@@ -75,6 +75,19 @@ time() = {{Year, Month, Day}, {Hour, Minute, Second}}
</desc>
</func>
<func>
+ <name>change_mode(Filename, Mode) -> ok | {error, Reason}</name>
+ <fsummary>Change permissions of a file</fsummary>
+ <type>
+ <v>Filename = name()</v>
+ <v>Mode = int()</v>
+ <v>Reason = ext_posix()</v>
+ </type>
+ <desc>
+ <p>Changes permissions of a file. See
+ <seealso marker="#write_file_info/2">write_file_info/2</seealso>.</p>
+ </desc>
+ </func>
+ <func>
<name>change_owner(Filename, Uid) -> ok | {error, Reason}</name>
<fsummary>Change owner of a file</fsummary>
<type>
diff --git a/lib/kernel/src/global.erl b/lib/kernel/src/global.erl
index cc0402da73..081e7e2f93 100644
--- a/lib/kernel/src/global.erl
+++ b/lib/kernel/src/global.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(global).
@@ -112,7 +112,7 @@
resolvers = [],
syncers = [] :: [pid()],
node_name = node() :: node(),
- the_locker, the_deleter, the_registrar, trace,
+ the_locker, the_registrar, trace,
global_lock_down = false
}).
@@ -153,6 +153,8 @@
%%% It can be removed later as can the deleter process.
%%% An extra process calling erlang:monitor() is sometimes created.
%%% The new_nodes messages has been augmented with the global lock id.
+%%%
+%%% R14A (OTP-8527): The deleter process has been removed.
start() ->
gen_server:start({local, global_name_server}, ?MODULE, [], []).
@@ -418,7 +420,6 @@ init([]) ->
S = #state{the_locker = start_the_locker(DoTrace),
trace = T0,
- the_deleter = start_the_deleter(self()),
the_registrar = start_the_registrar()},
S1 = trace_message(S, {init, node()}, []),
@@ -763,13 +764,16 @@ handle_cast({in_sync, Node, _IsKnown}, S) ->
%% Called when Pid on other node crashed
handle_cast({async_del_name, _Name, _Pid}, S) ->
- %% Sent from the_deleter at some node in the partition but node().
+ %% Sent from the_deleter at some node in the partition but node() (-R13B)
%% The DOWN message deletes the name.
+ %% R14A nodes and later do not send async_del_name messages.
{noreply, S};
handle_cast({async_del_lock, _ResourceId, _Pid}, S) ->
- %% Sent from global_name_server at some node in the partition but node().
+ %% Sent from global_name_server at some node in the partition but
+ %% node(). (-R13B)
%% The DOWN message deletes the lock.
+ %% R14A nodes and later do not send async_del_lock messages.
{noreply, S};
handle_cast(Request, S) ->
@@ -778,8 +782,6 @@ handle_cast(Request, S) ->
"handle_cast(~p, _)\n", [Request]),
{noreply, S}.
-handle_info({'EXIT', Deleter, _Reason}=Exit, #state{the_deleter=Deleter}=S) ->
- {stop, {deleter_died,Exit}, S#state{the_deleter=undefined}};
handle_info({'EXIT', Locker, _Reason}=Exit, #state{the_locker=Locker}=S) ->
{stop, {locker_died,Exit}, S#state{the_locker=undefined}};
handle_info({'EXIT', Registrar, _}=Exit, #state{the_registrar=Registrar}=S) ->
@@ -1348,30 +1350,13 @@ lock_still_set(PidOrNode, ExtraInfo, S) ->
[{?GLOBAL_RID, _LockReqId, PidRefs}] when is_pid(PidOrNode) ->
%% Name registration.
lists:keymember(PidOrNode, 1, PidRefs);
- [{?GLOBAL_RID, LockReqId, PidRefs}] when is_atom(PidOrNode) ->
- case extra_info(lock, ExtraInfo) of
- {?GLOBAL_RID, LockId} -> % R11B-4 or later
- LockReqId =:= LockId;
- undefined ->
- lock_still_set_old(PidOrNode, LockReqId, PidRefs)
- end;
+ [{?GLOBAL_RID, LockReqId, _PidRefs}] when is_atom(PidOrNode) ->
+ {?GLOBAL_RID, LockId} = extra_info(lock, ExtraInfo),
+ LockReqId =:= LockId;
[] ->
- %% If the global lock was not removed by a DOWN message
- %% then we have a node that do not monitor locking pids
- %% (pre R11B-3), or an R11B-3 node (which does not ensure
- %% that {new_nodes, ...} arrives before {del_lock, ...}).
not S#state.global_lock_down
end.
-%%% The following is probably overkill. It is possible that this node
-%%% has been locked again, but it is a rare occasion.
-lock_still_set_old(_Node, ReqId, _PidRefs) when is_pid(ReqId) ->
- %% Cannot do better than return true.
- true;
-lock_still_set_old(Node, ReqId, PidRefs) when is_list(ReqId) ->
- %% Connection, version > 4, but before R11B-4.
- [P || {P, _RPid, _Ref} <- PidRefs, node(P) =:= Node] =/= [].
-
extra_info(Tag, ExtraInfo) ->
%% ExtraInfo used to be a list of nodes (vsn 2).
case catch lists:keyfind(Tag, 1, ExtraInfo) of
@@ -1382,36 +1367,18 @@ extra_info(Tag, ExtraInfo) ->
end.
del_name(Ref, S) ->
- NameL = [{Name, Pid} ||
+ NameL = [Name ||
{_, Name} <- ets:lookup(global_pid_names, Ref),
- {_, Pid, _Method, _RPid, Ref1} <-
+ {_, _Pid, _Method, _RPid, Ref1} <-
ets:lookup(global_names, Name),
Ref1 =:= Ref],
- ?trace({async_del_name, self(), NameL, Ref}),
case NameL of
- [{Name, Pid}] ->
- _ = del_names(Name, Pid, S),
+ [Name] ->
delete_global_name2(Name, S);
[] ->
S
end.
-%% Send {async_del_name, ...} to old nodes (pre R11B-3).
-del_names(Name, Pid, S) ->
- Send = case ets:lookup(global_names_ext, Name) of
- [{Name, Pid, RegNode}] ->
- RegNode =:= node();
- [] ->
- node(Pid) =:= node()
- end,
- if
- Send ->
- ?trace({del_names, {pid,Pid}, {name,Name}}),
- S#state.the_deleter ! {delete_name, self(), Name, Pid};
- true ->
- ok
- end.
-
%% Keeps the entry in global_names for whereis_name/1.
delete_global_name_keep_pid(Name, S) ->
case ets:lookup(global_names, Name) of
@@ -1986,7 +1953,6 @@ pid_is_locking(Pid, PidRefs) ->
delete_lock(Ref, S0) ->
Locks = pid_locks(Ref),
- del_locks(Locks, Ref, S0#state.known),
F = fun({ResourceId, LockRequesterId, PidRefs}, S) ->
{Pid, _RPid, Ref} = lists:keyfind(Ref, 3, PidRefs),
remove_lock(ResourceId, LockRequesterId, Pid, PidRefs, true,S)
@@ -2003,20 +1969,6 @@ pid_locks(Ref) ->
rpid_is_locking(Ref, PidRefs) ->
lists:keyfind(Ref, 3, PidRefs) =/= false.
-%% Send {async_del_lock, ...} to old nodes (pre R11B-3).
-del_locks([{ResourceId, _LockReqId, PidRefs} | Tail], Ref, KnownNodes) ->
- {Pid, _RPid, Ref} = lists:keyfind(Ref, 3, PidRefs),
- case node(Pid) =:= node() of
- true ->
- gen_server:abcast(KnownNodes, global_name_server,
- {async_del_lock, ResourceId, Pid});
- false ->
- ok
- end,
- del_locks(Tail, Ref, KnownNodes);
-del_locks([], _Ref, _KnownNodes) ->
- ok.
-
handle_nodedown(Node, S) ->
%% DOWN signals from monitors have removed locks and registered names.
#state{known = Known, synced = Syncs} = S,
@@ -2147,51 +2099,6 @@ get_own_nodes() ->
OkTup
end.
-%%-----------------------------------------------------------------
-%% The deleter process is a satellite process to global_name_server
-%% that does background batch deleting of names when a process
-%% that had globally registered names dies. It is started by and
-%% linked to global_name_server.
-%%-----------------------------------------------------------------
-
-start_the_deleter(Global) ->
- spawn_link(fun() -> loop_the_deleter(Global) end).
-
-loop_the_deleter(Global) ->
- Deletions = collect_deletions(Global, []),
- ?trace({loop_the_deleter, self(), {deletions,Deletions},
- {names,get_names()}}),
- %% trans_all_known is called rather than trans/3 with nodes() as
- %% third argument. The reason is that known gets updated by
- %% new_nodes when the lock is still set. nodes() on the other hand
- %% could be updated later (if in_sync is received after the lock
- %% is gone). It is not likely that in_sync would be received after
- %% the lock has been taken here, but using trans_all_known makes it
- %% even less likely.
- trans_all_known(
- fun(Known) ->
- lists:map(
- fun({Name,Pid}) ->
- gen_server:abcast(Known, global_name_server,
- {async_del_name, Name, Pid})
- end, Deletions)
- end),
- loop_the_deleter(Global).
-
-collect_deletions(Global, Deletions) ->
- receive
- {delete_name, Global, Name, Pid} ->
- collect_deletions(Global, [{Name,Pid} | Deletions]);
- Other ->
- unexpected_message(Other, deleter),
- collect_deletions(Global, Deletions)
- after case Deletions of
- [] -> infinity;
- _ -> 0
- end ->
- lists:reverse(Deletions)
- end.
-
%% The registrar is a helper process that registers and unregisters
%% names. Since it never dies it assures that names are registered and
%% unregistered on all known nodes. It is started by and linked to
diff --git a/lib/kernel/test/global_SUITE.erl b/lib/kernel/test/global_SUITE.erl
index a8c68985e2..7a84ad5e75 100644
--- a/lib/kernel/test/global_SUITE.erl
+++ b/lib/kernel/test/global_SUITE.erl
@@ -1,25 +1,23 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(global_SUITE).
--compile(r11). % some code is run from r11-nodes
-
%-define(line_trace, 1).
-export([all/1,
@@ -2616,19 +2614,6 @@ proc(Parent) ->
name_exit(suite) -> [];
name_exit(doc) -> ["OTP-5563. Registered process dies."];
name_exit(Config) when is_list(Config) ->
- case ?t:is_release_available("r11b") of
- true ->
- StartOldFun =
- fun() ->
- {ok, N1} = start_node_rel(n_1, r11b, Config),
- {ok, N2} = start_node_rel(n_2, this, Config),
- [N1, N2]
- end,
- ?t:format("Test of r11~n"),
- do_name_exit(StartOldFun, old, Config);
- false ->
- ok
- end,
StartFun = fun() ->
{ok, N1} = start_node_rel(n_1, this, Config),
{ok, N2} = start_node_rel(n_2, this, Config),
@@ -2855,14 +2840,7 @@ many_nodes(Config) when is_list(Config) ->
N_nodes = quite_a_few_nodes(32),
{node_rel(1, N_nodes, this), N_nodes};
{unix, _} ->
- case ?t:is_release_available("r11b") of
- true ->
- This = node_rel(1, 16, this),
- R11B = node_rel(17, 32, r11b),
- {This ++ R11B, 32};
- false ->
- {node_rel(1, 32, this), 32}
- end;
+ {node_rel(1, 32, this), 32};
_ ->
{node_rel(1, 32, this), 32}
end,
@@ -3864,12 +3842,7 @@ start_node_rel(Name0, Rel, Config) ->
RelList ->
{RelList, ""}
end,
- Env = case Rel of
- r11b ->
- [{env, [{"ERL_R11B_FLAGS", []}]}];
- _ ->
- []
- end,
+ Env = [],
Pa = filename:dirname(code:which(?MODULE)),
Res = test_server:start_node(Name, peer,
[{args,
diff --git a/lib/megaco/doc/src/megaco_mib.xml b/lib/megaco/doc/src/megaco_mib.xml
index 3c0a549590..f1abe08fb5 100644
--- a/lib/megaco/doc/src/megaco_mib.xml
+++ b/lib/megaco/doc/src/megaco_mib.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2002</year><year>2009</year>
+ <year>2002</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>Megaco mib</title>
@@ -50,15 +50,15 @@
lightweight. I.e. the statistic counters are handled
separately by different entities of the application. For
instance our two transport module(s) (see <seealso marker="megaco_tcp#stats">megaco_tcp</seealso> and <seealso marker="megaco_udp#stats">megaco_udp</seealso>) maintain their
- own counters and the application engine (see <seealso marker="megaco#stats">megaco</seealso>) maintain it's own
+ own counters and the application engine (see <seealso marker="megaco#stats">megaco</seealso>) maintain its own
counters.</p>
<p>This also means that if a user implement their own transport
- service then it has to maintain it's own statistics.</p>
+ service then it has to maintain its own statistics.</p>
</section>
<section>
<title>Distribution</title>
- <p>Each megaco application maintains it's own set of counters. So
+ <p>Each megaco application maintains its own set of counters. So
in a large (distributed) MG/MGC it could be necessary to
collect the statistics from several nodes (each) running the
megaco application (only one of them with the transport).</p>
diff --git a/lib/megaco/doc/src/megaco_run.xml b/lib/megaco/doc/src/megaco_run.xml
index 3afc638bcf..9ed589b079 100644
--- a/lib/megaco/doc/src/megaco_run.xml
+++ b/lib/megaco/doc/src/megaco_run.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2000</year><year>2009</year>
+ <year>2000</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>Running the stack</title>
@@ -365,7 +365,7 @@
then the specified max message size (see the
<seealso marker="megaco#user_info">max_pdu_size</seealso> option).
Finally, if segmentation is decided, then each action reply
- will make up it's own (segment) message.</p>
+ will make up its own (segment) message.</p>
</item>
</list>
</section>
diff --git a/lib/megaco/doc/src/megaco_user.xml b/lib/megaco/doc/src/megaco_user.xml
index 37942007bc..6a0de29385 100644
--- a/lib/megaco/doc/src/megaco_user.xml
+++ b/lib/megaco/doc/src/megaco_user.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2000</year><year>2009</year>
+ <year>2000</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>megaco_user</title>
@@ -669,7 +669,7 @@ protocol_version() = integer() ]]></code>
<p>Invoked when a unexpected message is received</p>
<p>If a reply to a request is not received in time, the
megaco stack removes all info about the request from
- it's tables. If a reply should arrive after this has been
+ its tables. If a reply should arrive after this has been
done the app has no way of knowing where to send this message.
The message is delivered to the "user" by calling this
function on the local node (the node which has the link).</p>
diff --git a/lib/megaco/doc/src/notes_history.xml b/lib/megaco/doc/src/notes_history.xml
index 97aa4c66a5..640b62230f 100644
--- a/lib/megaco/doc/src/notes_history.xml
+++ b/lib/megaco/doc/src/notes_history.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2006</year><year>2009</year>
+ <year>2006</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>Megaco Release Notes history</title>
@@ -2764,7 +2764,7 @@
<p>Added a new configuration parameter, threaded.
This tells the megaco app, that all
transaction requests in a message should be executed
- in parallel (e.g. each in it's own process).
+ in parallel (e.g. each in its own process).
<br></br>See the
<seealso marker="megaco#user_info">threaded</seealso> parameter
of the user_info function (also conn_info).</p>
@@ -2911,7 +2911,7 @@
<title>Improvements and new features</title>
<list type="bulleted">
<item>
- <p>This is just a code up-/downgrade cleanup release. I.e. It's the
+ <p>This is just a code up-/downgrade cleanup release. I.e. it's the
same as version 1.2 minus the ugly stuff needed to handle up-/downgrade
from/to version 1.1.2, 1.1.1 and 1.1.0.</p>
</item>
diff --git a/lib/megaco/test/megaco_app_test.erl b/lib/megaco/test/megaco_app_test.erl
index 8e2148c236..597ec26338 100644
--- a/lib/megaco/test/megaco_app_test.erl
+++ b/lib/megaco/test/megaco_app_test.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2002-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -87,6 +87,10 @@ is_app(App) ->
case file:consult(File) of
{ok, [{application, App, AppFile}]} ->
{ok, AppFile};
+ {error, {LineNo, Mod, Code}} ->
+ IoList = lists:concat([File, ":", LineNo, ": ",
+ Mod:format_error(Code)]),
+ {error, list_to_atom(lists:flatten(IoList))};
Error ->
{error, {invalid_format, Error}}
end.
diff --git a/lib/reltool/src/Makefile b/lib/reltool/src/Makefile
index fa24efbb8c..7fac7cbf88 100644
--- a/lib/reltool/src/Makefile
+++ b/lib/reltool/src/Makefile
@@ -1,19 +1,19 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2009-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
include $(ERL_TOP)/make/target.mk
@@ -85,7 +85,7 @@ $(TARGET_FILES): $(HRL_FILES) $(INTERNAL_HRL_FILES)
# ----------------------------------------------------
# Release Target
-# ----------------------------------------------------
+# ----------------------------------------------------
include $(ERL_TOP)/make/otp_release_targets.mk
diff --git a/lib/reltool/src/reltool.erl b/lib/reltool/src/reltool.erl
index e6548bfe68..e6a8bca069 100644
--- a/lib/reltool/src/reltool.erl
+++ b/lib/reltool/src/reltool.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
-module(reltool).
@@ -24,106 +24,16 @@
start/0, start/1, start_link/1, debug/0, % GUI
start_server/1, get_server/1, stop/1,
get_config/1, get_config/3, get_rel/2, get_script/2,
- create_target/2, get_target_spec/1, eval_target_spec/3,
+ create_target/2, get_target_spec/1, eval_target_spec/3,
install/2
]).
--type file() :: string().
--type dir() :: string().
--type mod_cond() :: all | app | ebin | derived | none.
--type incl_cond() :: include | exclude | derived.
--type debug_info() :: keep | strip.
--type app_file() :: keep | strip | all.
--type re_regexp() :: string().
--type regexps() :: [re_regexp()] | {add, [re_regexp()]} | {del, [re_regexp()]} .
--type incl_sys_filters() :: regexps().
--type excl_sys_filters() :: regexps().
--type incl_app_filters() :: regexps().
--type excl_app_filters() :: regexps().
--type incl_archive_filters() :: regexps().
--type excl_archive_filters() :: regexps().
--type archive_opt() :: term().
--type root_dir() :: dir().
--type lib_dir() :: dir().
--type profile() :: development | embedded | standalone.
--type relocatable() :: boolean().
--type escript_file() :: file().
--type mod_name() :: atom().
--type app_name() :: atom().
--type app_vsn() :: string().
--type app_type() :: permanent | transient | temporary | load | none.
--type incl_app() :: app_name().
--type rel_name() :: string().
--type rel_vsn() :: string().
--type boot_rel() :: rel_name().
--type rel_app() :: app_name()
- | {app_name(), app_type()}
- | {app_name(), [incl_app()]}
- | {app_name(), app_type(), [incl_app()]}.
--type mod() :: {incl_cond, incl_cond()}
- | {debug_info, debug_info()}.
--type app() :: {vsn, app_vsn()}
- | {mod, mod_name(), mod()}
- | {mod_cond, mod_cond()}
- | {incl_cond, incl_cond()}
- | {app_file, app_file()}
- | {debug_info, debug_info()}
- | {incl_app_filters, incl_app_filters()}
- | {excl_app_filters, excl_app_filters()}
- | {incl_archive_filters, incl_archive_filters()}
- | {excl_archive_filters, excl_archive_filters()}.
--type escript() :: {incl_cond, incl_cond()}.
--type sys() :: {mod_cond, mod_cond()}
- | {incl_cond, incl_cond()}
- | {debug_info, debug_info()}
- | {app_file, app_file()}
- | {profile, profile()}
- | {incl_sys_filters, incl_sys_filters()}
- | {excl_sys_filters, excl_sys_filters()}
- | {incl_app_filters, incl_app_filters()}
- | {excl_app_filters, excl_app_filters()}
- | {incl_archive_filters, incl_archive_filters()}
- | {excl_archive_filters, excl_archive_filters()}
- | {archive_opts, [archive_opt()]}
- | {root_dir, root_dir()}
- | {lib_dirs, [lib_dir()]}
- | {boot_rel, boot_rel()}
- | {rel, rel_name(), rel_vsn(), [rel_app()]}
- | {relocatable, relocatable()}
- | {erts, app()}
- | {escript, escript_file(), [escript()]}
- | {app, app_name(), [app()]}.
--type config() :: {sys, [sys()]}.
--type option() :: {wx_debug, term()} | {trap_exit, boolean()} | config() | {config, config() | file()}.
--type options() :: [option()].
--type server_pid() :: pid().
--type window_pid() :: pid().
--type server() :: server_pid() | options().
--type rel_file() :: term().
--type script_file() :: term().
--type reason() :: string().
--type escript_arg() :: string().
-%%-type base_dir() :: dir().
-%%-type base_file() :: file().
-%%-type top_dir() :: file().
-%%-type top_file() :: file().
-%%-type target_spec() :: [target_spec()]
-%% | {create_dir, base_dir(), [target_spec()]}
-%% | {create_dir, base_dir(), top_dir(), [target_spec()]}
-%% | {archive, base_file(), [archive_opt()], [target_spec()]}
-%% | {copy_file, base_file()}
-%% | {copy_file, base_file(), top_file()}
-%% | {write_file, base_file(), iolist()}
-%% | {strip_beam_file, base_file()}.
--type target_spec() :: term().
--type target_dir() :: dir().
--type incl_defaults() :: boolean().
--type incl_derived() :: boolean().
+-include("reltool.hrl").
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Main function for escript
--spec main([escript_arg()]) -> ok.
+-spec main([escript_arg()]) -> ok.
main(_) ->
process_flag(trap_exit, true),
{ok, WinPid} = start_link([]),
@@ -164,7 +74,7 @@ start_link(Options) when is_list(Options) ->
{ok, WinPid};
{error, Reason} ->
{error, lists:flatten(io_lib:format("~p", [Reason]))}
- end.
+ end.
%% Start server process with options
-spec start_server(options()) -> {ok, server_pid()} | {error, reason()}.
@@ -200,7 +110,8 @@ stop(Pid) when is_pid(Pid) ->
end.
%% Internal library function
--spec eval_server(server(), fun((server_pid()) -> term())) -> {ok, server_pid()} | {error, reason()}.
+-spec eval_server(server(), fun((server_pid()) -> term())) ->
+ {ok, server_pid()} | {error, reason()}.
eval_server(Pid, Fun) when is_pid(Pid) ->
Fun(Pid);
eval_server(Options, Fun) when is_list(Options), is_function(Fun, 1) ->
@@ -212,39 +123,54 @@ eval_server(Options, Fun) when is_list(Options), is_function(Fun, 1) ->
{error, Reason} ->
{error, Reason}
end.
-
+
%% Get reltool configuration
-spec get_config(server()) -> {ok, config()} | {error, reason()}.
get_config(PidOrOption) ->
get_config(PidOrOption, false, false).
--spec get_config(server(), incl_defaults(), incl_derived()) -> {ok, config()} | {error, reason()}.
-get_config(PidOrOptions, InclDefaults, InclDerived) when is_pid(PidOrOptions); is_list(PidOrOptions) ->
- eval_server(PidOrOptions, fun(Pid) -> reltool_server:get_config(Pid, InclDefaults, InclDerived) end).
+-spec get_config(server(), incl_defaults(), incl_derived()) ->
+ {ok, config()} | {error, reason()}.
+get_config(PidOrOptions, InclDef, InclDeriv)
+ when is_pid(PidOrOptions); is_list(PidOrOptions) ->
+ eval_server(PidOrOptions,
+ fun(Pid) ->
+ reltool_server:get_config(Pid, InclDef, InclDeriv)
+ end).
%% Get contents of release file
-spec get_rel(server(), rel_name()) -> {ok, rel_file()} | {error, reason()}.
-get_rel(PidOrOptions, RelName) when is_pid(PidOrOptions); is_list(PidOrOptions) ->
- eval_server(PidOrOptions, fun(Pid) -> reltool_server:get_rel(Pid, RelName) end).
+get_rel(PidOrOptions, RelName)
+ when is_pid(PidOrOptions); is_list(PidOrOptions) ->
+ eval_server(PidOrOptions,
+ fun(Pid) -> reltool_server:get_rel(Pid, RelName) end).
%% Get contents of boot script file
--spec get_script(server(), rel_name()) -> {ok, script_file()} | {error, reason()}.
-get_script(PidOrOptions, RelName) when is_pid(PidOrOptions); is_list(PidOrOptions) ->
- eval_server(PidOrOptions, fun(Pid) -> reltool_server:get_script(Pid, RelName) end).
+-spec get_script(server(), rel_name()) ->
+ {ok, script_file()} | {error, reason()}.
+get_script(PidOrOptions, RelName)
+ when is_pid(PidOrOptions); is_list(PidOrOptions) ->
+ eval_server(PidOrOptions,
+ fun(Pid) -> reltool_server:get_script(Pid, RelName) end).
%% Generate a target system
-spec create_target(server(), target_dir()) -> ok | {error, reason()}.
-create_target(PidOrOptions, TargetDir) when is_pid(PidOrOptions); is_list(PidOrOptions) ->
- eval_server(PidOrOptions, fun(Pid) -> reltool_server:gen_target(Pid, TargetDir) end).
+create_target(PidOrOptions, TargetDir)
+ when is_pid(PidOrOptions); is_list(PidOrOptions) ->
+ eval_server(PidOrOptions,
+ fun(Pid) -> reltool_server:gen_target(Pid, TargetDir) end).
%% Generate a target system
-spec get_target_spec(server()) -> {ok, target_spec()} | {error, reason()}.
-get_target_spec(PidOrOptions) when is_pid(PidOrOptions); is_list(PidOrOptions) ->
+get_target_spec(PidOrOptions)
+ when is_pid(PidOrOptions); is_list(PidOrOptions) ->
eval_server(PidOrOptions, fun(Pid) -> reltool_server:gen_spec(Pid) end).
%% Generate a target system
--spec eval_target_spec(target_spec(), root_dir(), target_dir()) -> ok | {error, reason()}.
-eval_target_spec(Spec, SourceDir, TargetDir) when is_list(SourceDir), is_list(TargetDir) ->
+-spec eval_target_spec(target_spec(), root_dir(), target_dir()) ->
+ ok | {error, reason()}.
+eval_target_spec(Spec, SourceDir, TargetDir)
+ when is_list(SourceDir), is_list(TargetDir) ->
reltool_target:eval_spec(Spec, SourceDir, TargetDir).
%% Install a target system
diff --git a/lib/reltool/src/reltool.hrl b/lib/reltool/src/reltool.hrl
index e7d84f97db..8a6a2142fd 100644
--- a/lib/reltool/src/reltool.hrl
+++ b/lib/reltool/src/reltool.hrl
@@ -16,119 +16,144 @@
%%
%% %CopyrightEnd%
--define(APPLICATION, reltool).
+-define(APPLICATION, reltool).
-define(MISSING_APP, '*MISSING*').
-define(MISSING_APP_TEXT, "*MISSING*").
--record(common,
- {
- sys_debug, % term()
- wx_debug, % term()
- trap_exit, % bool()
- app_tab, % ets_tab()
- mod_tab, % ets_tab()
- mod_used_by_tab % ets_tab()
- }).
-
--record(sys,
- {
- %% Sources
- root_dir, % directory()
- lib_dirs, % [directory()]
- escripts, % [file()]
- mod_cond, % all | app | ebin | derived | none
- incl_cond, % include | exclude | derived
- apps, % [#app{}]
-
- %% Target cond
- boot_rel, % string()
- rels, % [#rel{}]
- emu_name, % string()
- profile, % standalone | development | embedded
- incl_sys_filters, % [regexp()]
- excl_sys_filters, % [regexp()]
- incl_app_filters, % [regexp()]
- excl_app_filters, % [regexp()]
- incl_archive_filters, % [regexp()]
- excl_archive_filters, % [regexp()]
- archive_opts, % [zip:create()]
- relocatable, % bool()
- app_type, % permanent | transient | temporary | load | none
- app_file, % keep | strip | all
- debug_info % keep | strip
- }).
-
--record(rel,
- {
- name, % string()
- vsn, % string()
- rel_apps % [#rel_app{}]
- }).
+-type file() :: string().
+-type dir() :: string().
+%% app - Include all modules in app file
+%% ebin - Include all modules on ebin directory
+%% derived - Include only those modules that others are dependent on
+-type mod_cond() :: all | app | ebin | derived | none.
+-type incl_cond() :: include | exclude | derived.
+-type debug_info() :: keep | strip.
+-type app_file() :: keep | strip | all.
+-type re_regexp() :: string(). % re:regexp()
+-type regexps() :: [re_regexp()] |
+ {add, [re_regexp()]} |
+ {del, [re_regexp()]} .
+-type incl_sys_filters() :: regexps().
+-type excl_sys_filters() :: regexps().
+-type incl_app_filters() :: regexps().
+-type excl_app_filters() :: regexps().
+-type incl_archive_filters() :: regexps().
+-type excl_archive_filters() :: regexps().
+-type archive_opt() :: term(). % zip:create()
+-type root_dir() :: dir().
+-type lib_dir() :: dir().
+-type profile() :: development | embedded | standalone.
+-type relocatable() :: boolean().
+-type escript_file() :: file().
+-type mod_name() :: atom().
+-type app_name() :: atom().
+-type app_vsn() :: string(). % e.g. "4.7"
+-type app_label() :: string().% e.g. "mnesia" or "mnesia-4.7"
+-type app_type() :: permanent | transient | temporary | load | none.
+-type incl_app() :: app_name().
+-type emu_name() :: string().
+-type rel_name() :: string().
+-type rel_vsn() :: string().
+-type boot_rel() :: rel_name().
+-type rel_app() :: app_name()
+ | {app_name(), app_type()}
+ | {app_name(), [incl_app()]}
+ | {app_name(), app_type(), [incl_app()]}.
+-type mod() :: {incl_cond, incl_cond()}
+ | {debug_info, debug_info()}.
+-type app() :: {vsn, app_vsn()}
+ | {mod, mod_name(), mod()}
+ | {mod_cond, mod_cond()}
+ | {incl_cond, incl_cond()}
+ | {app_file, app_file()}
+ | {debug_info, debug_info()}
+ | {incl_app_filters, incl_app_filters()}
+ | {excl_app_filters, excl_app_filters()}
+ | {incl_archive_filters, incl_archive_filters()}
+ | {excl_archive_filters, excl_archive_filters()}.
+-type escript() :: {incl_cond, incl_cond()}.
+-type sys() :: {mod_cond, mod_cond()}
+ | {incl_cond, incl_cond()}
+ | {debug_info, debug_info()}
+ | {app_file, app_file()}
+ | {profile, profile()}
+ | {incl_sys_filters, incl_sys_filters()}
+ | {excl_sys_filters, excl_sys_filters()}
+ | {incl_app_filters, incl_app_filters()}
+ | {excl_app_filters, excl_app_filters()}
+ | {incl_archive_filters, incl_archive_filters()}
+ | {excl_archive_filters, excl_archive_filters()}
+ | {archive_opts, [archive_opt()]}
+ | {root_dir, root_dir()}
+ | {lib_dirs, [lib_dir()]}
+ | {boot_rel, boot_rel()}
+ | {rel, rel_name(), rel_vsn(), [rel_app()]}
+ | {relocatable, relocatable()}
+ | {erts, app()}
+ | {escript, escript_file(), [escript()]}
+ | {app, app_name(), [app()]}.
+-type config() :: {sys, [sys()]}.
+-type option() :: {wx_debug, term()} |
+ {trap_exit, boolean()} |
+ config() |
+ {config, config() | file()}.
+-type options() :: [option()].
+-type server_pid() :: pid().
+-type window_pid() :: pid().
+-type server() :: server_pid() | options().
+-type rel_file() :: term().
+-type script_file() :: term().
+-type reason() :: string().
+-type escript_arg() :: string().
+-type base_dir() :: dir().
+-type base_file() :: file().
+-type top_dir() :: file().
+-type top_file() :: file().
+-type target_spec() :: [target_spec()]
+ | {create_dir, base_dir(), [target_spec()]}
+ | {create_dir, base_dir(), top_dir(), [target_spec()]}
+ | {archive,
+ base_file(),
+ [archive_opt()],
+ [target_spec()]}
+ | {copy_file, base_file()}
+ | {copy_file, base_file(), top_file()}
+ | {write_file, base_file(), iolist()}
+ | {strip_beam_file, base_file()}.
+-type target_dir() :: dir().
+-type incl_defaults() :: boolean().
+-type incl_derived() :: boolean().
+-type ets_tab() :: term().
+-type status() :: missing | ok.
--record(rel_app,
+-record(common,
{
- name, % atom()
- app_type, % permanent | transient | temporary | load | none
- incl_apps % [atom()]
+ sys_debug :: term(),
+ wx_debug :: term(),
+ trap_exit :: boolean(),
+ app_tab :: ets_tab(),
+ mod_tab :: ets_tab(),
+ mod_used_by_tab :: ets_tab()
}).
--record(app,
- {%% Static info
- name, % atom()
- is_escript, % bool()
- use_selected_vsn,% bool() | undefined
- active_dir, % dir_name()
- sorted_dirs, % [dir_name()]
- vsn, % string() e.g. "4.7"
- label, % string() e.g. "mnesia" or "mnesia-4.7"
- info, % #app_info{} | undefined
- mods, % [#mod{}]
-
- %% Static source cond
- mod_cond, % all | app | ebin | derived | none | undefined
- incl_cond, % include | exclude | derived | undefined
-
- %% Static target cond
- debug_info, % keep | strip | undefined
- app_file, % keep | strip | all | undefined
- app_type, % permanent | transient | temporary | load | none
- incl_app_filters, % [regexp()]
- excl_app_filters, % [regexp()]
- incl_archive_filters, % [regexp()]
- excl_archive_filters, % [regexp()]
- archive_opts, % [zip_create_opt()]
-
- %% Dynamic
- status, % missing | ok
- uses_mods, % [atom()]
- used_by_mods, % [atom()]
- uses_apps, % [atom()]
- used_by_apps, % [atom()]
- is_pre_included, % bool()
- is_included % bool()
- }).
-record(mod,
{%% Static
- name, % atom()
- app_name, % atom()
- incl_cond, % include | exclude | derived | undefined
- debug_info, % keep | strip | undefined
- is_app_mod, % bool(),
- is_ebin_mod, % bool(),
- uses_mods, % [module()]
- exists, % bool()
+ name :: mod_name(),
+ app_name :: app_name(),
+ incl_cond :: incl_cond() | undefined,
+ debug_info :: debug_info() | undefined,
+ is_app_mod :: boolean(),
+ is_ebin_mod :: boolean(),
+ uses_mods :: [mod_name()],
+ exists :: boolean(),
%% Dynamic
- status, % missing | ok
- used_by_mods, % [atom()]
- is_pre_included, % bool() | undefined
- is_included % bool() | undefined
+ status :: status(),
+ used_by_mods :: [mod_name()],
+ is_pre_included :: boolean() | undefined,
+ is_included :: boolean() | undefined
}).
-%% app - Include all modules in app file
-%% ebin - Include all modules on ebin directory
-%% derived - Include only those modules that others are dependent on
-
-record(app_info,
{
description = "",
@@ -145,8 +170,86 @@
start_phases = undefined
}).
+-record(app,
+ {%% Static info
+ name :: app_name(),
+ is_escript :: boolean(),
+ use_selected_vsn :: boolean() | undefined,
+ active_dir :: dir(),
+ sorted_dirs :: [dir()],
+ vsn :: app_vsn(),
+ label :: app_label(),
+ info :: #app_info{} | undefined,
+ mods :: [#mod{}],
+
+ %% Static source cond
+ mod_cond :: mod_cond() | undefined,
+ incl_cond :: incl_cond() | undefined,
+
+ %% Static target cond
+ debug_info :: debug_info() | undefined,
+ app_file :: app_file() | undefined,
+ app_type :: app_type(),
+ incl_app_filters :: incl_app_filters(),
+ excl_app_filters :: excl_app_filters(),
+ incl_archive_filters :: incl_archive_filters(),
+ excl_archive_filters :: excl_archive_filters(),
+ archive_opts :: [archive_opt()],
+
+ %% Dynamic
+ status :: status(),
+ uses_mods :: [mod_name()],
+ used_by_mods :: [mod_name()],
+ uses_apps :: [app_name()],
+ used_by_apps :: [app_name()],
+ is_pre_included :: boolean(),
+ is_included :: boolean()
+ }).
+
+-record(rel_app,
+ {
+ name :: app_name(),
+ app_type :: app_type(),
+ incl_apps :: [incl_app()]
+ }).
+
+-record(rel,
+ {
+ name :: rel_name(),
+ vsn :: rel_vsn(),
+ rel_apps :: [#rel_app{}]
+ }).
+
+-record(sys,
+ {
+ %% Sources
+ root_dir :: dir(),
+ lib_dirs :: [dir()],
+ escripts :: [file()],
+ mod_cond :: mod_cond(),
+ incl_cond :: incl_cond(),
+ apps :: [#app{}],
+
+ %% Target cond
+ boot_rel :: boot_rel(),
+ rels :: [#rel{}],
+ emu_name :: emu_name(),
+ profile :: profile(),
+ incl_sys_filters :: incl_sys_filters(),
+ excl_sys_filters :: excl_sys_filters(),
+ incl_app_filters :: incl_app_filters(),
+ excl_app_filters :: excl_app_filters(),
+ incl_archive_filters :: incl_archive_filters(),
+ excl_archive_filters :: excl_archive_filters(),
+ archive_opts :: [archive_opt()],
+ relocatable :: boolean(),
+ app_type :: app_type(),
+ app_file :: app_file(),
+ debug_info :: debug_info()
+ }).
+
-record(regexp, {source, compiled}).
-
+
-define(ERR_IMAGE, 0).
-define(WARN_IMAGE, 1).
-define(QUEST_IMAGE, 2).
@@ -170,7 +273,7 @@
-define(DEFAULT_DEBUG_INFO, keep).
-define(DEFAULT_INCL_ARCHIVE_FILTERS, [".*"]).
--define(DEFAULT_EXCL_ARCHIVE_FILTERS, ["^include$", "^priv$"]).
+-define(DEFAULT_EXCL_ARCHIVE_FILTERS, ["^include\$", "^priv\$"]).
-define(DEFAULT_ARCHIVE_OPTS, []).
-define(DEFAULT_INCL_SYS_FILTERS, [".*"]).
@@ -178,25 +281,27 @@
-define(DEFAULT_INCL_APP_FILTERS, [".*"]).
-define(DEFAULT_EXCL_APP_FILTERS, []).
--define(EMBEDDED_INCL_SYS_FILTERS, ["^bin",
+-define(EMBEDDED_INCL_SYS_FILTERS, ["^bin",
"^erts",
"^lib",
"^releases"]).
--define(EMBEDDED_EXCL_SYS_FILTERS, ["^bin/(erlc|dialyzer|typer)(|\\.exe)$",
- "^erts.*/bin/(erlc|dialyzer|typer)(|\\.exe)$",
- "^erts.*/bin/.*(debug|pdb)"]).
+-define(EMBEDDED_EXCL_SYS_FILTERS,
+ ["^bin/(erlc|dialyzer|typer)(|\\.exe)\$",
+ "^erts.*/bin/(erlc|dialyzer|typer)(|\\.exe)\$",
+ "^erts.*/bin/.*(debug|pdb)"]).
-define(EMBEDDED_INCL_APP_FILTERS, ["^ebin",
- "^priv",
+ "^priv",
"^include"]).
-define(EMBEDDED_EXCL_APP_FILTERS, []).
--define(STANDALONE_INCL_SYS_FILTERS, ["^bin/(erl|epmd)(|\\.exe|\\.ini)$",
- "^bin/start(|_clean).boot$",
+-define(STANDALONE_INCL_SYS_FILTERS, ["^bin/(erl|epmd)(|\\.exe|\\.ini)\$",
+ "^bin/start(|_clean).boot\$",
"^erts.*/bin",
- "^lib$"]).
--define(STANDALONE_EXCL_SYS_FILTERS, ["^erts.*/bin/(erlc|dialyzer|typer)(|\\.exe)$",
- "^erts.*/bin/(start|escript|to_erl|run_erl)(|\\.exe)$",
- "^erts.*/bin/.*(debug|pdb)"]).
--define(STANDALONE_INCL_APP_FILTERS, ["^ebin",
+ "^lib\$"]).
+-define(STANDALONE_EXCL_SYS_FILTERS,
+ ["^erts.*/bin/(erlc|dialyzer|typer)(|\\.exe)\$",
+ "^erts.*/bin/(start|escript|to_erl|run_erl)(|\\.exe)\$",
+ "^erts.*/bin/.*(debug|pdb)"]).
+-define(STANDALONE_INCL_APP_FILTERS, ["^ebin",
"^priv"]).
--define(STANDALONE_EXCL_APP_FILTERS, ["^ebin/.*\\.appup$"]).
+-define(STANDALONE_EXCL_APP_FILTERS, ["^ebin/.*\\.appup\$"]).
diff --git a/lib/reltool/src/reltool_app_win.erl b/lib/reltool/src/reltool_app_win.erl
index 6083493c02..70bd72b258 100644
--- a/lib/reltool/src/reltool_app_win.erl
+++ b/lib/reltool/src/reltool_app_win.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
-module(reltool_app_win).
@@ -34,7 +34,7 @@
-include_lib("wx/include/wx.hrl").
-include("reltool.hrl").
--record(state,
+-record(state,
{parent_pid,
xref_pid,
mod_wins,
@@ -63,7 +63,7 @@
%% -define(APPS_APP_COL_WIDTH, 250).
-define(CLOSE_ITEM, ?wxID_EXIT). %% Use OS specific version if available
--define(ABOUT_ITEM, ?wxID_ABOUT). %% Use OS specific
+-define(ABOUT_ITEM, ?wxID_ABOUT). %% Use OS specific
-define(CONTENTS_ITEM, 300).
-define(MODS_MOD_COL, 0).
@@ -79,7 +79,11 @@
%% Client
start_link(WxEnv, Xref, Common, AppName) ->
- proc_lib:start_link(?MODULE, init, [self(), WxEnv, Xref, Common, AppName], infinity, []).
+ proc_lib:start_link(?MODULE,
+ init,
+ [self(), WxEnv, Xref, Common, AppName],
+ infinity,
+ []).
raise(Pid) ->
reltool_utils:cast(Pid, raise).
@@ -121,7 +125,12 @@ loop(#state{xref_pid = Xref, common = C, app = App} = S) ->
receive
{system, From, Msg} ->
Dbg = C#common.sys_debug,
- sys:handle_system_msg(Msg, From, S#state.parent_pid, ?MODULE, Dbg, S);
+ sys:handle_system_msg(Msg,
+ From,
+ S#state.parent_pid,
+ ?MODULE,
+ Dbg,
+ S);
{cast, _From, raise} ->
wxFrame:raise(S#state.frame),
wxFrame:setFocus(S#state.frame),
@@ -131,7 +140,8 @@ loop(#state{xref_pid = Xref, common = C, app = App} = S) ->
{ok, App2} ->
{ok, Sys} = reltool_server:get_sys(Xref),
S2 = redraw_window(S#state{sys = Sys, app = App2}),
- [ok = reltool_mod_win:refresh(MW#mod_win.pid) || MW <- S2#state.mod_wins],
+ [ok = reltool_mod_win:refresh(MW#mod_win.pid) ||
+ MW <- S2#state.mod_wins],
?MODULE:loop(S2);
{error, _Reason} ->
wxFrame:destroy(S#state.frame),
@@ -139,7 +149,8 @@ loop(#state{xref_pid = Xref, common = C, app = App} = S) ->
end;
{call, ReplyTo, Ref, {open_mod, ModName}} ->
S2 = create_mod_window(S, ModName),
- {value, #mod_win{pid = ModPid}} = lists:keysearch(ModName, #mod_win.name, S2#state.mod_wins),
+ {value, #mod_win{pid = ModPid}} =
+ lists:keysearch(ModName, #mod_win.name, S2#state.mod_wins),
reltool_utils:reply(ReplyTo, Ref, {ok, ModPid}),
?MODULE:loop(S2);
#wx{event = #wxSize{}} = Wx ->
@@ -157,7 +168,9 @@ loop(#state{xref_pid = Xref, common = C, app = App} = S) ->
exit(Reason);
{'EXIT', Pid, _Reason} = Exit ->
exit_warning(Exit),
- S2 = S#state{mod_wins = lists:keydelete(Pid, #mod_win.pid, S#state.mod_wins)},
+ S2 = S#state{mod_wins = lists:keydelete(Pid,
+ #mod_win.pid,
+ S#state.mod_wins)},
?MODULE:loop(S2);
Msg ->
error_logger:format("~p~p got unexpected message:\n\t~p\n",
@@ -179,7 +192,7 @@ create_window(#state{app = App} = S) ->
StatusBar = wxFrame:createStatusBar(Frame,[]),
Book = wxNotebook:new(Panel, ?wxID_ANY, []),
-
+
S2 = S#state{frame = Frame,
panel = Panel,
book = Book,
@@ -210,12 +223,16 @@ create_apps_page(S, Derived) ->
Lower = wxBoxSizer:new(?wxHORIZONTAL),
UsedByCtrl = create_apps_list_ctrl(Panel, Upper, "Used by"),
- wxSizer:add(Upper, wxStaticLine:new(Panel, [{style, ?wxLI_VERTICAL}]), [{border, 2}, {flag, ?wxALL bor ?wxEXPAND}]),
-
+ wxSizer:add(Upper,
+ wxStaticLine:new(Panel, [{style, ?wxLI_VERTICAL}]),
+ [{border, 2}, {flag, ?wxALL bor ?wxEXPAND}]),
+
RequiredCtrl = create_apps_list_ctrl(Panel, Upper, "Required"),
- wxSizer:add(Upper, wxStaticLine:new(Panel, [{style, ?wxLI_VERTICAL}]), [{border, 2}, {flag, ?wxALL bor ?wxEXPAND}]),
+ wxSizer:add(Upper, wxStaticLine:new(Panel, [{style, ?wxLI_VERTICAL}]),
+ [{border, 2}, {flag, ?wxALL bor ?wxEXPAND}]),
InclCtrl = create_apps_list_ctrl(Panel, Upper, "Included"),
- wxSizer:add(Upper, wxStaticLine:new(Panel, [{style, ?wxLI_VERTICAL}]), [{border, 2}, {flag, ?wxALL bor ?wxEXPAND}]),
+ wxSizer:add(Upper, wxStaticLine:new(Panel, [{style, ?wxLI_VERTICAL}]),
+ [{border, 2}, {flag, ?wxALL bor ?wxEXPAND}]),
UsesCtrl = create_apps_list_ctrl(Panel, Upper, "Uses"),
S2 = S#state{app_required_ctrl = RequiredCtrl,
app_used_by_ctrl = UsedByCtrl,
@@ -262,8 +279,10 @@ create_apps_list_ctrl(Panel, Sizer, Text) ->
[{border, 2},
{flag, ?wxALL bor ?wxEXPAND},
{proportion, 1}]),
- wxEvtHandler:connect(ListCtrl, size, [{skip, true}, {userData, apps_list_ctrl}]),
- wxListCtrl:connect(ListCtrl, command_list_item_activated, [{userData, open_app}]),
+ wxEvtHandler:connect(ListCtrl, size,
+ [{skip, true}, {userData, apps_list_ctrl}]),
+ wxListCtrl:connect(ListCtrl, command_list_item_activated,
+ [{userData, open_app}]),
wxWindow:connect(ListCtrl, enter_window),
ListCtrl.
@@ -271,9 +290,20 @@ create_deps_page(S, Derived) ->
Panel = wxPanel:new(S#state.book, []),
Main = wxBoxSizer:new(?wxHORIZONTAL),
- UsedByCtrl = create_mods_list_ctrl(Panel, Main, "Modules used by others", " and their applications", undefined, undefined),
- wxSizer:add(Main, wxStaticLine:new(Panel, [{style, ?wxLI_VERTICAL}]), [{border, 2}, {flag, ?wxALL bor ?wxEXPAND}]),
- UsesCtrl = create_mods_list_ctrl(Panel, Main, "Used modules", " and their applications", undefined, undefined),
+ UsedByCtrl = create_mods_list_ctrl(Panel,
+ Main,
+ "Modules used by others",
+ " and their applications",
+ undefined,
+ undefined),
+ wxSizer:add(Main, wxStaticLine:new(Panel, [{style, ?wxLI_VERTICAL}]),
+ [{border, 2}, {flag, ?wxALL bor ?wxEXPAND}]),
+ UsesCtrl = create_mods_list_ctrl(Panel,
+ Main,
+ "Used modules",
+ " and their applications",
+ undefined,
+ undefined),
S2 = S#state{deps_used_by_ctrl = UsedByCtrl,
deps_uses_ctrl = UsesCtrl},
redraw_mods(S2, Derived),
@@ -285,13 +315,36 @@ create_mods_page(S, Derived) ->
Panel = wxPanel:new(S#state.book, []),
MainSz = wxBoxSizer:new(?wxHORIZONTAL),
- SourceCtrl = create_mods_list_ctrl(Panel, MainSz, ?source, "", whitelist_add, blacklist_add),
- wxSizer:add(MainSz, wxStaticLine:new(Panel, [{style, ?wxLI_VERTICAL}]), [{border, 2}, {flag, ?wxALL bor ?wxEXPAND}]),
- WhiteCtrl = create_mods_list_ctrl(Panel, MainSz, ?whitelist, "", whitelist_del, blacklist_add),
- wxSizer:add(MainSz, wxStaticLine:new(Panel, [{style, ?wxLI_VERTICAL}]), [{border, 2}, {flag, ?wxALL bor ?wxEXPAND}]),
- BlackCtrl = create_mods_list_ctrl(Panel, MainSz, ?blacklist, "", whitelist_add, blacklist_del),
- wxSizer:add(MainSz, wxStaticLine:new(Panel, [{style, ?wxLI_VERTICAL}]), [{border, 2}, {flag, ?wxALL bor ?wxEXPAND}]),
- DerivedCtrl = create_mods_list_ctrl(Panel, MainSz, ?derived, "", whitelist_add, blacklist_add),
+ SourceCtrl = create_mods_list_ctrl(Panel,
+ MainSz,
+ ?source,
+ "",
+ whitelist_add,
+ blacklist_add),
+ wxSizer:add(MainSz, wxStaticLine:new(Panel, [{style, ?wxLI_VERTICAL}]),
+ [{border, 2}, {flag, ?wxALL bor ?wxEXPAND}]),
+ WhiteCtrl = create_mods_list_ctrl(Panel,
+ MainSz,
+ ?whitelist,
+ "",
+ whitelist_del,
+ blacklist_add),
+ wxSizer:add(MainSz, wxStaticLine:new(Panel, [{style, ?wxLI_VERTICAL}]),
+ [{border, 2}, {flag, ?wxALL bor ?wxEXPAND}]),
+ BlackCtrl = create_mods_list_ctrl(Panel,
+ MainSz,
+ ?blacklist,
+ "",
+ whitelist_add,
+ blacklist_del),
+ wxSizer:add(MainSz, wxStaticLine:new(Panel, [{style, ?wxLI_VERTICAL}]),
+ [{border, 2}, {flag, ?wxALL bor ?wxEXPAND}]),
+ DerivedCtrl = create_mods_list_ctrl(Panel,
+ MainSz,
+ ?derived,
+ "",
+ whitelist_add,
+ blacklist_add),
S2 = S#state{mods_source_ctrl = SourceCtrl,
mods_white_ctrl = WhiteCtrl,
mods_black_ctrl = BlackCtrl,
@@ -309,7 +362,8 @@ create_mods_list_ctrl(Panel, OuterSz, Title, AppText, Tick, Cross) ->
%% ?wxLC_SINGLE_SEL bor
?wxHSCROLL bor
?wxVSCROLL}]),
- ToolTip = "Select module(s) or open separate module window with a double click.",
+ ToolTip = "Select module(s) or open separate module "
+ "window with a double click.",
wxListCtrl:setToolTip(ListCtrl, ToolTip),
%% Prep images
@@ -326,7 +380,8 @@ create_mods_list_ctrl(Panel, OuterSz, Title, AppText, Tick, Cross) ->
true ->
wxListItem:setText(ListItem, AppText),
wxListCtrl:insertColumn(ListCtrl, ?MODS_APP_COL, ListItem),
- %% wxListCtrl:setColumnWidth(ListCtrl, ?MODS_APP_COL, ?MODS_APP_COL_WIDTH),
+ %% wxListCtrl:setColumnWidth(ListCtrl, ?MODS_APP_COL,
+ %% ?MODS_APP_COL_WIDTH),
2;
false ->
1
@@ -336,9 +391,11 @@ create_mods_list_ctrl(Panel, OuterSz, Title, AppText, Tick, Cross) ->
ButtonSz = wxBoxSizer:new(?wxHORIZONTAL),
create_button(Panel, ButtonSz, ListCtrl, Title, "wxART_TICK_MARK", Tick),
create_button(Panel, ButtonSz, ListCtrl, Title, "wxART_CROSS_MARK", Cross),
- wxEvtHandler:connect(ListCtrl, size, [{skip, true}, {userData, mods_list_ctrl}]),
- wxListCtrl:connect(ListCtrl, command_list_item_activated, [{userData, open_mod}]),
- wxWindow:connect(ListCtrl, enter_window),
+ wxEvtHandler:connect(ListCtrl, size,
+ [{skip, true}, {userData, mods_list_ctrl}]),
+ wxListCtrl:connect(ListCtrl, command_list_item_activated,
+ [{userData, open_mod}]),
+ wxWindow:connect(ListCtrl, enter_window),
InnerSz = wxBoxSizer:new(?wxVERTICAL),
wxSizer:add(InnerSz, ListCtrl,
[{border, 2},
@@ -377,7 +434,7 @@ action_to_tool_tip(Label, Action) ->
"Remove selected module(s)from whitelist.";
blacklist_add when Label =:= ?blacklist ->
"Remove selected module(s) from blacklist.";
- blacklist_add ->
+ blacklist_add ->
"Add selected module(s) to blacklist.";
blacklist_del ->
"Remove selected module(s) from blacklist."
@@ -444,8 +501,8 @@ create_config_page(#state{app = App} = S) ->
wxNotebook:addPage(S2#state.book, Panel, "Application settings", []),
S2.
-create_double_box(Panel, Sizer, TopLabel,
- OuterText, OuterData,
+create_double_box(Panel, Sizer, TopLabel,
+ OuterText, OuterData,
InnerText, InnerData,
InternalLabel, InternalChoices, InternalChoiceData) ->
TopSizer = wxStaticBoxSizer:new(?wxVERTICAL, Panel,
@@ -457,10 +514,10 @@ create_double_box(Panel, Sizer, TopLabel,
[{userData, OuterData}]),
InnerRadio = wxRadioButton:new(Panel, ?wxID_ANY, InnerText),
wxEvtHandler:connect(InnerRadio, command_radiobutton_selected,
- [{userData, InnerData}]),
- InnerBox = wxRadioBox:new(Panel,
+ [{userData, InnerData}]),
+ InnerBox = wxRadioBox:new(Panel,
?wxID_ANY,
- InternalLabel,
+ InternalLabel,
?wxDefaultPosition,
?wxDefaultSize,
InternalChoices,
@@ -487,29 +544,38 @@ handle_event(#state{sys = Sys, app = App} = S, Wx) ->
#wx{obj = ObjRef, event = #wxMouse{type = enter_window}} ->
wxWindow:setFocus(ObjRef),
S;
- #wx{obj= ListCtrl, userData = mods_list_ctrl, event = #wxSize{type = size, size = {W, _H}}} ->
+ #wx{obj= ListCtrl,
+ userData = mods_list_ctrl,
+ event = #wxSize{type = size, size = {W, _H}}} ->
HasApps = (wxListCtrl:getColumnCount(ListCtrl) > 1),
case HasApps of
false ->
wxListCtrl:setColumnWidth(ListCtrl, ?MODS_MOD_COL, W);
true ->
- wxListCtrl:setColumnWidth(ListCtrl, ?MODS_MOD_COL, (2 * W) div 3),
+ wxListCtrl:setColumnWidth(ListCtrl,
+ ?MODS_MOD_COL,
+ (2 * W) div 3),
wxListCtrl:setColumnWidth(ListCtrl, ?MODS_APP_COL, W div 3)
end,
S;
- #wx{obj= ListCtrl, userData = apps_list_ctrl, event = #wxSize{type = size, size = {W, _H}}} ->
+ #wx{obj = ListCtrl,
+ userData = apps_list_ctrl,
+ event = #wxSize{type = size, size = {W, _H}}} ->
wxListCtrl:setColumnWidth(ListCtrl, ?APPS_APP_COL, W),
S;
#wx{userData = open_app,
obj = ListCtrl,
- event = #wxList{type = command_list_item_activated, itemIndex = Pos}} ->
+ event = #wxList{type = command_list_item_activated,
+ itemIndex = Pos}} ->
AppBase = wxListCtrl:getItemText(ListCtrl, Pos),
{AppName, _AppVsn} = reltool_utils:split_app_name(AppBase),
- {ok, _AppPid} = reltool_sys_win:open_app(S#state.parent_pid, AppName),
+ {ok, _AppPid} = reltool_sys_win:open_app(S#state.parent_pid,
+ AppName),
S;
#wx{userData = open_mod,
obj = ListCtrl,
- event = #wxList{type = command_list_item_activated, itemIndex = Pos}} ->
+ event = #wxList{type = command_list_item_activated,
+ itemIndex = Pos}} ->
ModName = list_to_atom(wxListCtrl:getItemText(ListCtrl, Pos)),
create_mod_window(S, ModName);
#wx{userData = global_incl_cond} ->
@@ -560,16 +626,19 @@ handle_event(#state{sys = Sys, app = App} = S, Wx) ->
Items = reltool_utils:get_items(ListCtrl),
handle_mod_button(S, Items, Action);
_ ->
- error_logger:format("~p~p got unexpected app event from wx:\n\t~p\n",
+ error_logger:format("~p~p got unexpected app event from "
+ "wx:\n\t~p\n",
[?MODULE, self(), Wx]),
S
end.
-create_mod_window(#state{parent_pid = RelPid, xref_pid = Xref, common = C} = S, ModName) ->
+create_mod_window(#state{parent_pid = RelPid, xref_pid = Xref, common = C} = S,
+ ModName) ->
case lists:keysearch(ModName, #mod_win.name, S#state.mod_wins) of
false ->
WxEnv = wx:get_env(),
- {ok, Pid} = reltool_mod_win:start_link(WxEnv, Xref, RelPid, C, ModName),
+ {ok, Pid} =
+ reltool_mod_win:start_link(WxEnv, Xref, RelPid, C, ModName),
MW = #mod_win{name = ModName, pid = Pid},
S#state{mod_wins = [MW | S#state.mod_wins]};
{value, MW} ->
@@ -578,7 +647,9 @@ create_mod_window(#state{parent_pid = RelPid, xref_pid = Xref, common = C} = S,
end.
handle_mod_button(#state{app = App} = S, Items, Action) ->
- App2 = lists:foldl(fun(Item, A) -> move_mod(A, Item, Action) end, App, Items),
+ App2 = lists:foldl(fun(Item, A) -> move_mod(A, Item, Action) end,
+ App,
+ Items),
{ok, App3} = reltool_sys_win:set_app(S#state.parent_pid, App2),
S2 = S#state{app = App3},
redraw_window(S2).
@@ -587,7 +658,7 @@ move_mod(App, {_ItemNo, ModStr}, Action) ->
ModName = list_to_atom(ModStr),
Mods = App#app.mods,
{value, M} = lists:keysearch(ModName, #mod.name, Mods),
- AppCond =
+ AppCond =
case Action of
whitelist_add ->
case M#mod.incl_cond of
@@ -597,12 +668,13 @@ move_mod(App, {_ItemNo, ModStr}, Action) ->
end;
whitelist_del ->
undefined;
- blacklist_add ->
+ blacklist_add ->
exclude;
blacklist_del ->
undefined;
_ ->
- error_logger:format("~p~p got unexpected mod button event: ~p\n\t ~p\n",
+ error_logger:format("~p~p got unexpected mod "
+ "button event: ~p\n\t ~p\n",
[?MODULE, self(), ModName, Action]),
M#mod.incl_cond
end,
@@ -623,7 +695,10 @@ change_mod_cond(S, App, NewModCond) ->
redraw_window(S2).
change_version(S, App, NewDir) ->
- App2 = App#app{active_dir = NewDir, label = undefined, vsn = undefined, info = undefined},
+ App2 = App#app{active_dir = NewDir,
+ label = undefined,
+ vsn = undefined,
+ info = undefined},
{ok, App3} = reltool_sys_win:set_app(S#state.parent_pid, App2),
Title = app_title(App3),
wxFrame:setTitle(S#state.frame, Title),
@@ -635,8 +710,14 @@ redraw_apps(#state{app = #app{info = AppInfo},
app_incl_ctrl = InclCtrl,
app_uses_ctrl = UsesCtrl,
xref_pid = Xref},
- {_SourceMods, _WhiteMods, _BlackMods, _DerivedMods, UsedByMods, UsesMods}) ->
- UsedByApps = lists:usort([{M#mod.app_name, Image} || {Image, _, M} <- UsedByMods]),
+ {_SourceMods,
+ _WhiteMods,
+ _BlackMods,
+ _DerivedMods,
+ UsedByMods,
+ UsesMods}) ->
+ UsedByApps =
+ lists:usort([{M#mod.app_name, Image} || {Image, _, M} <- UsedByMods]),
Select =
fun(AppName) ->
{ok, App} = reltool_server:get_app(Xref, AppName),
@@ -647,7 +728,8 @@ redraw_apps(#state{app = #app{info = AppInfo},
end,
RequiredApps = lists:sort(lists:map(Select, AppInfo#app_info.applications)),
InclApps = lists:map(Select, AppInfo#app_info.incl_apps),
- UsesApps = lists:usort([{M#mod.app_name, Image} || {Image, _, M} <- UsesMods]),
+ UsesApps =
+ lists:usort([{M#mod.app_name, Image} || {Image, _, M} <- UsesMods]),
do_redraw_apps(UsedByCtrl, UsedByApps),
do_redraw_apps(RequiredCtrl, RequiredApps),
do_redraw_apps(InclCtrl, InclApps),
@@ -656,19 +738,26 @@ redraw_apps(#state{app = #app{info = AppInfo},
do_redraw_apps(ListCtrl, []) ->
wxListCtrl:deleteAllItems(ListCtrl);
- %% wxListCtrl:setColumnWidth(ListCtrl, ?APPS_APP_COL, ?wxLIST_AUTOSIZE_USEHEADER);
+ %% wxListCtrl:setColumnWidth(ListCtrl, ?APPS_APP_COL,
+%% ?wxLIST_AUTOSIZE_USEHEADER);
do_redraw_apps(ListCtrl, AppImages) ->
wxListCtrl:deleteAllItems(ListCtrl),
Add =
fun({AppName, ImageId}, {Row, Prev}) when AppName =/= Prev ->
- wxListCtrl:insertItem(ListCtrl, Row, ""),
- if (Row rem 2) =:= 0 ->
- wxListCtrl:setItemBackgroundColour(ListCtrl, Row, {240,240,255});
+ wxListCtrl:insertItem(ListCtrl, Row, ""),
+ if (Row rem 2) =:= 0 ->
+ wxListCtrl:setItemBackgroundColour(ListCtrl,
+ Row,
+ {240,240,255});
true ->
ignore
end,
Str = atom_to_list(AppName),
- wxListCtrl:setItem(ListCtrl, Row, ?APPS_APP_COL, Str, [{imageId, ImageId}]),
+ wxListCtrl:setItem(ListCtrl,
+ Row,
+ ?APPS_APP_COL,
+ Str,
+ [{imageId, ImageId}]),
{Row + 1, AppName};
({_, _}, Acc) ->
Acc
@@ -688,8 +777,13 @@ redraw_mods(#state{mods_source_ctrl = SourceCtrl,
deps_uses_ctrl = UsesCtrl,
app = #app{is_pre_included = IsPre, is_included = IsIncl},
status_bar = Bar},
- {SourceMods, WhiteMods, BlackMods, DerivedMods, UsedByMods, UsesMods}) ->
- InclStatus =
+ {SourceMods,
+ WhiteMods,
+ BlackMods,
+ DerivedMods,
+ UsedByMods,
+ UsesMods}) ->
+ InclStatus =
case IsIncl of
true when IsPre =:= true -> "Whitelist - ";
true -> "Derived - ";
@@ -711,7 +805,7 @@ app_to_mods(#state{xref_pid = Xref, app = App}) ->
SourceMods = [M || M <- App#app.mods,
M#mod.is_included =/= true,
M#mod.is_pre_included =/= false],
- WhiteMods = [M || M <- App#app.mods,
+ WhiteMods = [M || M <- App#app.mods,
M#mod.is_pre_included =:= true],
BlackMods = [M || M <- App#app.mods,
M#mod.is_pre_included =:= false],
@@ -722,7 +816,8 @@ app_to_mods(#state{xref_pid = Xref, app = App}) ->
fun(ModName) when is_atom(ModName) ->
{ok, M} = reltool_server:get_mod(Xref, ModName),
if
- M#mod.app_name =:= App#app.name, M#mod.is_included =:= true ->
+ M#mod.app_name =:= App#app.name,
+ M#mod.is_included =:= true ->
false;
true ->
{true, M}
@@ -780,20 +875,26 @@ opt_redraw_mods(undefined, _ImageMods) ->
opt_redraw_mods(ListCtrl, ImageMods) ->
HasApps = (wxListCtrl:getColumnCount(ListCtrl) > 1),
do_redraw_mods(ListCtrl, ImageMods, HasApps).
-
+
do_redraw_mods(ListCtrl, [], _HasApps) ->
wxListCtrl:deleteAllItems(ListCtrl);
do_redraw_mods(ListCtrl, ImageMods, HasApps) ->
wxListCtrl:deleteAllItems(ListCtrl),
Add =
fun({ImageId, AppName, #mod{name = ModName}}, Row) ->
- wxListCtrl:insertItem(ListCtrl, Row, ""),
- if (Row rem 2) =:= 0 ->
- wxListCtrl:setItemBackgroundColour(ListCtrl, Row, {240,240,255});
+ wxListCtrl:insertItem(ListCtrl, Row, ""),
+ if (Row rem 2) =:= 0 ->
+ wxListCtrl:setItemBackgroundColour(ListCtrl,
+ Row,
+ {240,240,255});
true ->
ignore
end,
- wxListCtrl:setItem(ListCtrl, Row, ?MODS_MOD_COL, atom_to_list(ModName), [{imageId, ImageId}]),
+ wxListCtrl:setItem(ListCtrl,
+ Row,
+ ?MODS_MOD_COL,
+ atom_to_list(ModName),
+ [{imageId, ImageId}]),
case HasApps of
false ->
ok;
@@ -842,13 +943,14 @@ redraw_config(#state{sys = #sys{incl_cond = GlobalIncl,
SelectedRadio,
SourceBox,
fun(true) ->
- reltool_utils:elem_to_index(ActiveDir, SortedDirs) - 1;
+ reltool_utils:elem_to_index(ActiveDir,
+ SortedDirs) - 1;
(false) ->
0
end).
redraw_double_box(Global, Local, GlobalRadio, LocalRadio, LocalBox, GetChoice) ->
- AppCond =
+ AppCond =
case Local of
undefined ->
wxRadioButton:setValue(GlobalRadio, true),
diff --git a/lib/reltool/src/reltool_fgraph.erl b/lib/reltool/src/reltool_fgraph.erl
index 09c4f8c8ce..2e8f39e418 100644
--- a/lib/reltool/src/reltool_fgraph.erl
+++ b/lib/reltool/src/reltool_fgraph.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
-module(reltool_fgraph).
@@ -80,7 +80,7 @@ foreach(Fun, Fg) ->
end, Fg),
Fg.
-map(Fun, Fg) ->
+map(Fun, Fg) ->
lists:foreach(fun
(Key) -> put(Key,Fun(get(Key)))
end, Fg),
@@ -105,7 +105,9 @@ step(Vs, Es) -> step(Vs, Es, {0,0}).
step(Vs, Es, Pa) ->
?MODULE:map(fun
(Node = {_, #fg_v{ type = static }}) -> Node;
- ({Key, Value = #fg_v{ p = {Px, Py}, v = {Vx, Vy}, type = dynamic}}) when is_float(Px), is_float(Py), is_float(Vx), is_float(Vy) ->
+ ({Key, Value = #fg_v{ p = {Px, Py}, v = {Vx, Vy}, type = dynamic}})
+ when is_float(Px), is_float(Py),
+ is_float(Vx), is_float(Vy) ->
F0 = {0.0,0.0},
F1 = coulomb_repulsion(Key, Value, Vs, F0),
F2 = hooke_attraction(Key, Value, Vs, Es, F1),
@@ -115,7 +117,7 @@ step(Vs, Es, Pa) ->
Vx1 = (Vx + ?fg_th*Fx)*?fg_damp,
Vy1 = (Vy + ?fg_th*Fy)*?fg_damp,
-
+
Px1 = Px + ?fg_th*Vx1,
Py1 = Py + ?fg_th*Vy1,
@@ -123,14 +125,16 @@ step(Vs, Es, Pa) ->
(Node) -> Node
end, Vs).
-point_attraction(_, #fg_v{ p = P0 }, Pa, {Fx, Fy}) when is_float(Fx), is_float(Fy) ->
+point_attraction(_, #fg_v{ p = P0 }, Pa, {Fx, Fy})
+ when is_float(Fx), is_float(Fy) ->
K = 20,
L = 150,
{R, {Cx,Cy}} = composition(P0, Pa),
F = -K*?fg_stretch*(R - L),
{Fx + Cx*F, Fy + Cy*F}.
-
-coulomb_repulsion(K0, #fg_v{ p = P0, q = Q0}, Vs, {Fx0, Fy0}) when is_float(Fx0), is_float(Fy0) ->
+
+coulomb_repulsion(K0, #fg_v{ p = P0, q = Q0}, Vs, {Fx0, Fy0})
+ when is_float(Fx0), is_float(Fy0) ->
?MODULE:foldl(fun
({K1, _}, F) when K1 == K0 -> F;
({_, #fg_v{ p = P1, q = Q1}}, {Fx, Fy}) ->
@@ -140,7 +144,8 @@ coulomb_repulsion(K0, #fg_v{ p = P0, q = Q0}, Vs, {Fx0, Fy0}) when is_float(Fx0)
(_, F) -> F
end, {Fx0, Fy0}, Vs).
-hooke_attraction(Key0, #fg_v{ p = P0 }, Vs, Es, {Fx0, Fy0}) when is_float(Fx0), is_float(Fy0) ->
+hooke_attraction(Key0, #fg_v{ p = P0 }, Vs, Es, {Fx0, Fy0})
+ when is_float(Fx0), is_float(Fy0) ->
?MODULE:foldl(fun
({{Key1,Key1}, _}, F) -> F;
({{Key1,Key2}, #fg_e{ l = L, k = K}}, {Fx, Fy}) when Key1 =:= Key0->
@@ -153,10 +158,11 @@ hooke_attraction(Key0, #fg_v{ p = P0 }, Vs, Es, {Fx0, Fy0}) when is_float(Fx0),
{R, {Cx,Cy}} = composition(P0, P1),
F = -K*?fg_stretch*(R - L),
{Fx + Cx*F, Fy + Cy*F};
- (_, F) -> F
+ (_, F) -> F
end, {Fx0, Fy0}, Es).
-composition({Px1, Py1}, {Px0, Py0}) when is_float(Px1), is_float(Py1), is_float(Px0), is_float(Py0) ->
+composition({Px1, Py1}, {Px0, Py0})
+ when is_float(Px1), is_float(Py1), is_float(Px0), is_float(Py0) ->
Dx = Px1 - Px0,
Dy = Py1 - Py0,
R = math:sqrt(Dx*Dx + Dy*Dy + 0.001),
diff --git a/lib/reltool/src/reltool_fgraph_win.erl b/lib/reltool/src/reltool_fgraph_win.erl
index b063fb94ba..b0deb1bab2 100644
--- a/lib/reltool/src/reltool_fgraph_win.erl
+++ b/lib/reltool/src/reltool_fgraph_win.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
-module(reltool_fgraph_win).
@@ -95,7 +95,7 @@ change_node(Pid, Key, Color) -> Pid ! {change_node, Key, Color}.
add_link(Pid, {FromKey, ToKey}) -> Pid ! {add_link, {FromKey, ToKey}}.
del_link(Pid, {FromKey, ToKey}) -> Pid ! {del_link, {FromKey, ToKey}}.
-stop(Pid, Reason) ->
+stop(Pid, Reason) ->
Ref = erlang:monitor(process, Pid),
Pid ! {stop, Reason},
receive
@@ -110,21 +110,24 @@ new(Parent, Options) ->
Me = self(),
Pid = spawn_link(fun() -> init([Parent, Me, Env, Options]) end),
receive {Pid, {?MODULE, Panel}} -> {Pid,Panel} end.
-
+
init([ParentWin, Pid, Env, Options]) ->
wx:set_env(Env),
-
+
BReset = wxButton:new(ParentWin, ?reset, [{label,"Reset"}]),
BFreeze = wxButton:new(ParentWin, ?freeze, [{label,"Freeze"}]),
BLock = wxButton:new(ParentWin, ?lock, [{label,"Lock"}]),
BUnlock = wxButton:new(ParentWin, ?unlock, [{label,"Unlock"}]),
BDelete = wxButton:new(ParentWin, ?delete, [{label,"Delete"}]),
- SQ = wxSlider:new(ParentWin, ?q_slider, ?default_q, 1, 500, [{style, ?wxVERTICAL}]),
- SL = wxSlider:new(ParentWin, ?l_slider, ?default_l, 1, 500, [{style, ?wxVERTICAL}]),
- SK = wxSlider:new(ParentWin, ?k_slider, ?default_k, 1, 500, [{style, ?wxVERTICAL}]),
+ SQ = wxSlider:new(ParentWin, ?q_slider, ?default_q, 1, 500,
+ [{style, ?wxVERTICAL}]),
+ SL = wxSlider:new(ParentWin, ?l_slider, ?default_l, 1, 500,
+ [{style, ?wxVERTICAL}]),
+ SK = wxSlider:new(ParentWin, ?k_slider, ?default_k, 1, 500,
+ [{style, ?wxVERTICAL}]),
Win = wxWindow:new(ParentWin, ?wxID_ANY, Options),
-
+
ButtonSizer = wxBoxSizer:new(?wxVERTICAL),
wxSizer:add(ButtonSizer, BReset),
wxSizer:add(ButtonSizer, BFreeze),
@@ -141,31 +144,34 @@ init([ParentWin, Pid, Env, Options]) ->
WindowSizer = wxBoxSizer:new(?wxHORIZONTAL),
wxSizer:add(WindowSizer, ButtonSizer, [{flag, ?wxEXPAND}, {proportion, 0}]),
wxSizer:add(WindowSizer, Win, [{flag, ?wxEXPAND}, {proportion, 1}]),
-
+
wxButton:setToolTip(BReset, "Remove selection and unlock all nodes."),
wxButton:setToolTip(BFreeze, "Start/stop redraw of screen."),
wxButton:setToolTip(BLock, "Lock all selected nodes."),
wxButton:setToolTip(BUnlock, "Unlock all selected nodes."),
wxButton:setToolTip(BDelete, "Delete all selected nodes."),
- wxButton:setToolTip(SQ, "Control repulsive force. This can also be controlled with the mouse wheel on the canvas."),
+ wxButton:setToolTip(SQ, "Control repulsive force. This can also be"
+ " controlled with the mouse wheel on the canvas."),
wxButton:setToolTip(SL, "Control link length."),
wxButton:setToolTip(SK, "Control attractive force. Use with care."),
- wxButton:setToolTip(Win,
- "Drag mouse while left mouse button is pressed to perform various operations. "
- "Combine with control key to select. Combine with shift key to lock single node."),
+ wxButton:setToolTip(Win,
+ "Drag mouse while left mouse button is pressed "
+ "to perform various operations. "
+ "Combine with control key to select. Combine "
+ "with shift key to lock single node."),
wxButton:connect(BReset, command_button_clicked),
wxButton:connect(BFreeze, command_button_clicked),
wxButton:connect(BLock, command_button_clicked),
wxButton:connect(BUnlock, command_button_clicked),
wxButton:connect(BDelete, command_button_clicked),
-
+
wxWindow:connect(SQ, command_slider_updated),
wxWindow:connect(SL, command_slider_updated),
wxWindow:connect(SK, command_slider_updated),
-
- wxWindow:connect(Win, enter_window),
+
+ wxWindow:connect(Win, enter_window),
wxWindow:connect(Win, move),
wxWindow:connect(Win, motion),
wxWindow:connect(Win, mousewheel),
@@ -174,7 +180,7 @@ init([ParentWin, Pid, Env, Options]) ->
wxWindow:connect(Win, left_up),
wxWindow:connect(Win, right_down),
wxWindow:connect(Win, paint, [{skip, true}]),
-
+
Pen = wxPen:new({0,0,0}, [{width, 3}]),
Font = wxFont:new(12, ?wxSWISS, ?wxNORMAL, ?wxNORMAL,[]),
Brush = wxBrush:new({0,0,0}),
@@ -182,13 +188,13 @@ init([ParentWin, Pid, Env, Options]) ->
Pid ! {self(), {?MODULE, WindowSizer}},
wxWindow:setFocus(Win), %% Get keyboard focus
-
+
Vs = reltool_fgraph:new(),
Es = reltool_fgraph:new(),
Me = self(),
Ticker = spawn_link(fun() -> ticker_init(Me) end),
-
+
loop( #state{ parent_pid = Pid,
q_slider = SQ,
l_slider = SL,
@@ -215,14 +221,17 @@ graph_add_node(Key, Color, G = #graph{ vs = Vs}) ->
M = 0.5, % mass
P = {float(450 + random:uniform(100)),
float(450 + random:uniform(100))},
- G#graph{ vs = reltool_fgraph:add(Key, #fg_v{ p = P, m = M, q = Q, color = Color}, Vs)}.
+ G#graph{ vs = reltool_fgraph:add(Key,
+ #fg_v{ p = P, m = M, q = Q, color = Color},
+ Vs)}.
graph_change_node(Key, Color, G) ->
case reltool_fgraph:get(Key, G#graph.vs) of
- undefined ->
+ undefined ->
G;
V ->
- G#graph{ vs = reltool_fgraph:set(Key, V#fg_v{ color = Color }, G#graph.vs)}
+ G#graph{ vs = reltool_fgraph:set(Key, V#fg_v{ color = Color },
+ G#graph.vs)}
end.
graph_del_node(Key, G = #graph{ vs = Vs0, es = Es0}) ->
@@ -231,7 +240,7 @@ graph_del_node(Key, G = #graph{ vs = Vs0, es = Es0}) ->
G#graph{ vs = Vs, es = Es }.
graph_add_link(Key0, Key1, G = #graph{ es = Es}) ->
- K = 60.0, % attractive force
+ K = 60.0, % attractive force
L = 5.0, % spring length
G#graph{ es = reltool_fgraph:add({Key0, Key1}, #fg_e{ k = K, l = L}, Es) }.
@@ -249,15 +258,17 @@ ticker_loop(Pid, Time) ->
D = timer:now_diff(T1, T0)/1000,
case round(40 - D) of
Ms when Ms < 0 ->
- %io:format("ticker: wait is 0 ms [fg ~7s ms] [fps ~7s]~n", [s(D), s(1000/D)]),
+ %io:format("ticker: wait is 0 ms [fg ~7s ms] [fps ~7s]~n",
+ % [s(D), s(1000/D)]),
ticker_loop(Pid, 0);
Ms ->
- %io:format("ticker: wait is ~3s ms [fg ~7s ms] [fps ~7s]~n", [s(Ms), s(D), s(1000/40)]),
+ %io:format("ticker: wait is ~3s ms [fg ~7s ms] [fps ~7s]~n",
+ % [s(Ms), s(D), s(1000/40)]),
ticker_loop(Pid, Ms)
end
end.
-delete_edges(Es, []) ->
+delete_edges(Es, []) ->
Es;
delete_edges(Es, [Key|Keys]) ->
Edges = reltool_fgraph:foldl(fun
@@ -269,7 +280,7 @@ delete_edges(Es, [Key|Keys]) ->
(K, Esi) -> reltool_fgraph:del(K, Esi)
end, Es, Edges),
delete_edges(Es1, Keys).
-
+
set_charge(Q, Vs) -> % Repulsive force
F = fun({Key, Value}) -> {Key, Value#fg_v{ q = Q}} end,
@@ -295,36 +306,47 @@ loop(S, G) ->
wxSlider:setValue(S#state.k_slider, K),
Es = set_length(L, G#graph.es),
Es2 = set_spring(K, Es),
-
- Vs2 = reltool_fgraph:map(fun({Key, V}) ->
- {Key, V#fg_v{selected = false, type = dynamic, q = Q}}
- end,
- G#graph.vs),
-
- {Xs, Ys} = reltool_fgraph:foldl(fun({_Key, #fg_v{p = {X, Y}}}, {Xs, Ys}) ->
- {[X| Xs], [Y | Ys]}
- end,
- {[], []},
- Vs2),
+
+ Vs2 =
+ reltool_fgraph:map(fun({Key, V}) ->
+ {Key, V#fg_v{selected = false,
+ type = dynamic,
+ q = Q}}
+ end,
+ G#graph.vs),
+
+ {Xs, Ys} =
+ reltool_fgraph:foldl(fun({_Key,
+ #fg_v{p = {X, Y}}}, {Xs, Ys}) ->
+ {[X| Xs], [Y | Ys]}
+ end,
+ {[], []},
+ Vs2),
%% io:format("Before: ~p\n", [G#graph.offset]),
Offset =
case length(Xs) of
0 ->
{0, 0};
N ->
- MeanX = (lists:sum(Xs) / N),
+ MeanX = (lists:sum(Xs) / N),
MeanY = (lists:sum(Ys) / N),
{SizeX, SizeY} = wxWindow:getSize(S#state.window),
- %% io:format("Min: ~p\n", [{lists:min(Xs), lists:min(Ys)}]),
- %% io:format("Mean: ~p\n", [{MeanX, MeanY}]),
- %% io:format("Max: ~p\n", [{lists:max(Xs), lists:max(Ys)}]),
+ %% io:format("Min: ~p\n",
+ %% [{lists:min(Xs), lists:min(Ys)}]),
+ %% io:format("Mean: ~p\n",
+ %% [{MeanX, MeanY}]),
+ %% io:format("Max: ~p\n",
+ %% [{lists:max(Xs), lists:max(Ys)}]),
%% io:format("Size: ~p\n", [{SizeX, SizeY}]),
%% {XM - (XS / 2), YM - (YS / 2)}
%% {0 - lists:min(Xs) + 20, 0 - lists:min(Ys) + 20}
{0 - MeanX + (SizeX / 2), 0 - MeanY + (SizeY / 2)}
end,
%% io:format("After: ~p\n", [Offset]),
- loop(S, G#graph{vs = Vs2, es = Es2, offset = Offset, offset_state = false});
+ loop(S, G#graph{vs = Vs2,
+ es = Es2,
+ offset = Offset,
+ offset_state = false});
#wx{id = ?freeze, event = #wxCommand{type=command_button_clicked}} ->
%% Start/stop redraw of screen
IsFrozen =
@@ -354,10 +376,15 @@ loop(S, G) ->
loop(S, G#graph{ vs = Vs });
#wx{id = ?delete, event = #wxCommand{type=command_button_clicked}} ->
%% Delete all selected nodes
- {Vs1, Keys} = reltool_fgraph:foldl(fun
- ({Key, #fg_v{ selected = true}}, {Vs, Ks}) ->
- {reltool_fgraph:del(Key,Vs), [Key|Ks]};
- (_, {Vs, Ks}) -> {Vs, Ks}
+ {Vs1, Keys} =
+ reltool_fgraph:foldl(fun
+ ({Key,
+ #fg_v{ selected = true}},
+ {Vs, Ks}) ->
+ {reltool_fgraph:del(Key,Vs),
+ [Key|Ks]};
+ (_, {Vs, Ks}) ->
+ {Vs, Ks}
end, {G#graph.vs,[]}, G#graph.vs),
Es = delete_edges(G#graph.es, Keys),
loop(S, G#graph{ vs = Vs1, es = Es});
@@ -368,20 +395,26 @@ loop(S, G) ->
#wx{id = ?move, event = #wxCommand{type=command_button_clicked}} ->
loop(S#state{ mouse_act = ?move }, G);
- #wx{id = ?q_slider, event = #wxCommand{type=command_slider_updated, commandInt = Q}} ->
+ #wx{id = ?q_slider, event = #wxCommand{type=command_slider_updated,
+ commandInt = Q}} ->
loop(S, G#graph{ vs = set_charge(Q, G#graph.vs)});
- #wx{id = ?l_slider, event = #wxCommand{type=command_slider_updated, commandInt = L}} ->
+ #wx{id = ?l_slider, event = #wxCommand{type=command_slider_updated,
+ commandInt = L}} ->
loop(S, G#graph{ es = set_length(L, G#graph.es)});
- #wx{id = ?k_slider, event = #wxCommand{type=command_slider_updated, commandInt = K}} ->
+ #wx{id = ?k_slider, event = #wxCommand{type=command_slider_updated,
+ commandInt = K}} ->
loop(S, G#graph{ es = set_spring(K, G#graph.es)});
#wx{event=#wxKey{type=key_up, keyCode = 127}} -> % delete
{Vs1, Keys} =
- reltool_fgraph:foldl(fun({Key, #fg_v{ selected = true}}, {Vs, Ks}) ->
- {reltool_fgraph:del(Key,Vs), [Key|Ks]};
- (_, {Vs, Ks}) ->
- {Vs, Ks}
- end,
- {G#graph.vs,[]}, G#graph.vs),
+ reltool_fgraph:foldl(fun({Key,
+ #fg_v{ selected = true}},
+ {Vs, Ks}) ->
+ {reltool_fgraph:del(Key,Vs),
+ [Key|Ks]};
+ (_, {Vs, Ks}) ->
+ {Vs, Ks}
+ end,
+ {G#graph.vs,[]}, G#graph.vs),
Es = delete_edges(G#graph.es, Keys),
loop(S, G#graph{ vs = Vs1, es = Es});
#wx{event=#wxKey{type=key_up}} ->
@@ -390,7 +423,11 @@ loop(S, G) ->
loop(S, G);
%% mouse
- #wx{event=#wxMouse{type=left_down, shiftDown=Shift, controlDown=Ctrl, x=X, y=Y}} ->
+ #wx{event=#wxMouse{type=left_down,
+ shiftDown=Shift,
+ controlDown=Ctrl,
+ x=X,
+ y=Y}} ->
if
Shift ->
loop(S, mouse_left_down_move(G, {X,Y}));
@@ -401,7 +438,11 @@ loop(S, G) ->
S#state.mouse_act =:= ?select ->
loop(S, mouse_left_down_select(G, {X,Y}))
end;
- #wx{event=#wxMouse{type=motion, shiftDown=Shift, controlDown=Ctrl, x=X, y=Y}} ->
+ #wx{event=#wxMouse{type=motion,
+ shiftDown=Shift,
+ controlDown=Ctrl,
+ x=X,
+ y=Y}} ->
if
Shift ->
loop(S, mouse_motion_move(G, {X,Y}));
@@ -412,7 +453,9 @@ loop(S, G) ->
S#state.mouse_act =:= ?select ->
loop(S, mouse_motion_select(G, {X,Y}))
end;
- #wx{event=#wxMouse{type=left_up, shiftDown=Shift, controlDown=Ctrl, x=X, y=Y}} ->
+ #wx{event=#wxMouse{type=left_up,
+ shiftDown=Shift,
+ controlDown=Ctrl, x=X, y=Y}} ->
if
Shift ->
loop(S, mouse_left_up_move(G, {X,Y}, Shift));
@@ -424,7 +467,7 @@ loop(S, G) ->
loop(S, mouse_left_up_select(G, {X,Y}))
end;
- #wx{event=#wxMouse{type=right_down,x=_X,y=_Y}} ->
+ #wx{event=#wxMouse{type=right_down,x=_X,y=_Y}} ->
loop(S, G);
%% mouse wheel
#wx{event=#wxMouse{type=mousewheel, wheelRotation=Rotation}} ->
@@ -436,7 +479,7 @@ loop(S, G) ->
Rotation < 0 ->
wxSlider:setValue(S#state.q_slider, Q + 4),
loop(S, G#graph{ vs = set_charge(Q + 4, G#graph.vs) });
- true ->
+ true ->
loop(S, G)
end;
@@ -448,7 +491,7 @@ loop(S, G) ->
redraw(S, G),
loop(S, G);
#wx{obj=Win,event=#wxMouse{type=enter_window}} ->
- wxWindow:setFocus(Win),
+ wxWindow:setFocus(Win),
loop(S, G);
%% Graph manipulation
@@ -465,9 +508,11 @@ loop(S, G) ->
{Req, redraw} ->
{SizeX, SizeY} = wxWindow:getSize(S#state.window),
- Vs = reltool_fgraph:step(G#graph.vs, G#graph.es, {SizeX/2.0 - 20.0, SizeY/2.0}),
+ Vs = reltool_fgraph:step(G#graph.vs,
+ G#graph.es,
+ {SizeX/2.0 - 20.0, SizeY/2.0}),
case S#state.is_frozen of
- false ->
+ false ->
Req ! {self(), ok};
true ->
ignore
@@ -481,7 +526,7 @@ loop(S, G) ->
Other ->
error_logger:format("~p~p got unexpected message:\n\t~p\n",
- [?MODULE, self(), Other]),
+ [?MODULE, self(), Other]),
loop(S, G)
end.
@@ -494,17 +539,22 @@ mouse_left_down_move(#graph{vs = Vs} = G, {X, Y}) ->
false ->
G#graph{ offset_state = {X,Y}};
{true, Key} ->
- V = #fg_v{ type = Type} = reltool_fgraph:get(Key, Vs),
- G#graph{ vs = reltool_fgraph:set(Key, V#fg_v{ type = moving}, Vs), select = {node, Key, Type, X, Y} }
+ V = #fg_v{ type = Type} = reltool_fgraph:get(Key, Vs),
+ G#graph{ vs = reltool_fgraph:set(Key,
+ V#fg_v{ type = moving}, Vs),
+ select = {node, Key, Type, X, Y} }
end.
coord_to_key(#graph{vs = Vs, offset = {Xo, Yo}}, {X, Y}) ->
Xr = X - Xo,
Yr = Y - Yo,
- reltool_fgraph:foldl(fun({Key, #fg_v{ p = {Px, Py}}}, _) when abs(Px - Xr) < 10,
- abs(Py - Yr) < 10 -> {true, Key};
- (_, Out) -> Out
- end, false, Vs).
+ reltool_fgraph:foldl(fun({Key, #fg_v{ p = {Px, Py}}}, _)
+ when abs(Px - Xr) < 10,
+ abs(Py - Yr) < 10 ->
+ {true, Key};
+ (_, Out) ->
+ Out
+ end, false, Vs).
mouse_left_up_select(G, {_X,_Y}) ->
case G#graph.select of
@@ -524,7 +574,7 @@ mouse_left_up_select(G, {_X,_Y}) ->
_ ->
G#graph{ select = none}
end.
-
+
mouse_left_up_move(G = #graph{ select = Select, vs = Vs} = G, {X,Y}, Shift) ->
case Select of
{node, Key, _, X, Y} ->
@@ -543,7 +593,7 @@ mouse_left_up_move(G = #graph{ select = Select, vs = Vs} = G, {X,Y}, Shift) ->
_ ->
G#graph{ select = none, offset_state = false }
end.
-
+
mouse_motion_select(G, {X,Y}) ->
case G#graph.select of
{P0, _P1} -> G#graph{ select = {P0, {X,Y}}};
@@ -557,11 +607,11 @@ mouse_motion_move(G = #graph{ select = {node, Key, _, _, _}, vs = Vs}, {X,Y}) ->
G#graph{ vs = reltool_fgraph:set(Key, V2, Vs) };
mouse_motion_move(G, {X,Y}) ->
case G#graph.offset_state of
- {X1,Y1} ->
+ {X1,Y1} ->
{X0, Y0} = G#graph.offset,
G#graph{ offset_state = {X,Y},
offset = {X0 - (X1 - X), Y0 - (Y1 - Y)} };
- _ ->
+ _ ->
G
end.
@@ -574,9 +624,9 @@ redraw(#state{window=Win}, G) ->
wxClientDC:destroy(DC0),
ok.
-redraw(DC, _Size, G) ->
- wx:batch(fun() ->
-
+redraw(DC, _Size, G) ->
+ wx:batch(fun() ->
+
Pen = G#graph.pen,
Font = G#graph.font,
Brush = G#graph.brush,
@@ -587,7 +637,7 @@ redraw(DC, _Size, G) ->
wxPen:setWidth(Pen, 1),
wxDC:clear(DC),
- % draw vertices and edges
+ % draw vertices and edges
wxPen:setColour(Pen, ?color_fg),
wxDC:setPen(DC,Pen),
@@ -602,7 +652,9 @@ redraw(DC, _Size, G) ->
% draw information text
wxFont:setWeight(Font,?wxNORMAL),
- draw_text(DC, reltool_fgraph:size(G#graph.vs), reltool_fgraph:size(G#graph.es), G#graph.ke),
+ draw_text(DC,
+ reltool_fgraph:'size'(G#graph.vs),
+ reltool_fgraph:'size'(G#graph.es), G#graph.ke),
ok
end).
@@ -612,14 +664,14 @@ draw_select_box(DC, {{X0,Y0}, {X1,Y1}}) ->
draw_line(DC, {X1,Y1}, {X0,Y1}, {0,0}),
draw_line(DC, {X0,Y0}, {X0,Y1}, {0,0}),
ok;
-draw_select_box(_DC, _) ->
+draw_select_box(_DC, _) ->
ok.
draw_es(DC, Vs, Es, Po, Pen, Brush) ->
reltool_fgraph:foreach(fun
({{K1, K2}, _}) ->
- #fg_v{ p = P1} = reltool_fgraph:get(K1, Vs),
- #fg_v{ p = P2} = reltool_fgraph:get(K2, Vs),
+ #fg_v{ p = P1} = reltool_fgraph:'get'(K1, Vs),
+ #fg_v{ p = P2} = reltool_fgraph:'get'(K2, Vs),
draw_arrow(DC, P1, P2, Po, Pen, Brush)
end, Es).
@@ -650,10 +702,15 @@ draw_arrow(DC, {X0,Y0}, {X1, Y1}, {X, Y}, Pen, Brush) ->
wxDC:drawPolygon(DC, Points, []).
draw_line(DC, {X0,Y0}, {X1, Y1}, {X, Y}) ->
- wxDC:drawLine(DC, {round(X0 + X), round(Y0 + Y)}, {round(X1 + X), round(Y1 + Y)}).
-
+ wxDC:drawLine(DC,
+ {round(X0 + X), round(Y0 + Y)},
+ {round(X1 + X), round(Y1 + Y)}).
+
draw_vs(DC, Vs, {Xo, Yo}, Pen, Brush) ->
- reltool_fgraph:foreach(fun({Key, #fg_v{ p ={X, Y}, color = Color, selected = Sel}}) ->
+ reltool_fgraph:foreach(fun({Key,
+ #fg_v{p ={X, Y},
+ color = Color,
+ selected = Sel}}) ->
String = s(Key),
case Sel of
true ->
@@ -661,35 +718,49 @@ draw_vs(DC, Vs, {Xo, Yo}, Pen, Brush) ->
wxBrush:setColour(Brush, ?color_bg),
wxDC:setPen(DC,Pen),
wxDC:setBrush(DC, Brush),
- SelProps = {round(X-12 + Xo), round(Y-12 + Yo), 24, 24},
- wxDC:drawRoundedRectangle(DC, SelProps, float(?ARC_R)),
+ SelProps = {round(X-12 + Xo),
+ round(Y-12 + Yo),
+ 24,
+ 24},
+ wxDC:drawRoundedRectangle(DC,
+ SelProps,
+ float(?ARC_R)),
ok;
false ->
ok
end,
case Color of
- default ->
+ default ->
wxPen:setColour(Pen, ?color_default),
- wxBrush:setColour(Brush, ?color_default_bg);
- alternate ->
- wxPen:setColour(Pen, ?color_alternate),
- wxBrush:setColour(Brush, ?color_alternate_bg);
+ wxBrush:setColour(Brush,
+ ?color_default_bg);
+ alternate ->
+ wxPen:setColour(Pen,
+ ?color_alternate),
+ wxBrush:setColour(Brush,
+ ?color_alternate_bg);
{FgColor, BgColor} ->
wxPen:setColour(Pen, FgColor),
- wxBrush:setColour(Brush, BgColor);
+ wxBrush:setColour(Brush, BgColor);
Color ->
wxPen:setColour(Pen, Color),
wxBrush:setColour(Brush, Color)
end,
wxDC:setPen(DC,Pen),
wxDC:setBrush(DC, Brush),
- NodeProps = {round(X-8 + Xo),round(Y-8 + Yo),17,17},
- wxDC:drawRoundedRectangle(DC, NodeProps, float(?ARC_R)),
- wxDC:drawText(DC, String, {round(X + Xo), round(Y + Yo)}),
+ NodeProps = {round(X-8 + Xo),
+ round(Y-8 + Yo),17,17},
+ wxDC:drawRoundedRectangle(DC,
+ NodeProps,
+ float(?ARC_R)),
+ wxDC:drawText(DC,
+ String,
+ {round(X + Xo),
+ round(Y + Yo)}),
ok;
(_) ->
ok
- end,
+ end,
Vs).
draw_text(DC, Nvs, Nes, _KE) ->
@@ -720,7 +791,7 @@ calc_point({X, Y}, Length, Radians) ->
%% %% Convert from an angle in radians to degrees
%% radians_to_degrees(Radians) ->
%% Radians * 180 / math:pi().
-%%
+%%
%% %% Convert from an angle in degrees to radians
%% degrees_to_radians(Degrees) ->
%% Degrees * math:pi() / 180.
diff --git a/lib/reltool/src/reltool_mod_win.erl b/lib/reltool/src/reltool_mod_win.erl
index c05f73cde8..c2544cc2d8 100644
--- a/lib/reltool/src/reltool_mod_win.erl
+++ b/lib/reltool/src/reltool_mod_win.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
-module(reltool_mod_win).
@@ -34,7 +34,7 @@
-include_lib("wx/include/wx.hrl").
-include("reltool.hrl").
--record(state,
+-record(state,
{parent_pid,
xref_pid,
rel_pid,
@@ -73,7 +73,7 @@
-define(WIN_HEIGHT, 600).
-define(CLOSE_ITEM, ?wxID_EXIT). %% Use OS specific version if available
--define(ABOUT_ITEM, ?wxID_ABOUT). %% Use OS specific
+-define(ABOUT_ITEM, ?wxID_ABOUT). %% Use OS specific
-define(CONTENTS_ITEM, 300).
-define(SEARCH_ENTRY, 413).
-define(GOTO_ENTRY, 414).
@@ -87,7 +87,11 @@
%% Client
start_link(WxEnv, Xref, RelPid, Common, ModName) ->
- proc_lib:start_link(?MODULE, init, [self(), WxEnv, Xref, RelPid, Common, ModName], infinity, []).
+ proc_lib:start_link(?MODULE,
+ init,
+ [self(), WxEnv, Xref, RelPid, Common, ModName],
+ infinity,
+ []).
raise(Pid) ->
reltool_utils:cast(Pid, raise).
@@ -127,10 +131,15 @@ loop(#state{xref_pid = Xref, common = C, mod = Mod} = S) ->
receive
Msg ->
%% io:format("~s~p -> ~p\n", [S#state.name, self(), Msg]),
- case Msg of
+ case Msg of
{system, From, SysMsg} ->
Dbg = C#common.sys_debug,
- sys:handle_system_msg(SysMsg, From, S#state.parent_pid, ?MODULE, Dbg, S);
+ sys:handle_system_msg(SysMsg,
+ From,
+ S#state.parent_pid,
+ ?MODULE,
+ Dbg,
+ S);
{cast, _From, raise} ->
wxFrame:raise(S#state.frame),
wxFrame:setFocus(S#state.frame),
@@ -169,7 +178,7 @@ loop(#state{xref_pid = Xref, common = C, mod = Mod} = S) ->
create_window(#state{mod = Mod, name = ModStr} = S) ->
Title = atom_to_list(?APPLICATION) ++ " - " ++
- atom_to_list(Mod#mod.app_name) ++ " - " ++
+ atom_to_list(Mod#mod.app_name) ++ " - " ++
ModStr ++ ".erl",
Frame = wxFrame:new(wx:null(), ?wxID_ANY, Title, []),
%% wxFrame:setSize(Frame, {?WIN_WIDTH, ?WIN_HEIGHT}),
@@ -177,7 +186,7 @@ create_window(#state{mod = Mod, name = ModStr} = S) ->
StatusBar = wxFrame:createStatusBar(Frame,[]),
Book = wxNotebook:new(Panel, ?wxID_ANY, []),
-
+
S2 = S#state{frame = Frame,
panel = Panel,
book = Book,
@@ -204,11 +213,17 @@ create_deps_page(S) ->
Panel = wxPanel:new(S#state.book, []),
Main = wxBoxSizer:new(?wxHORIZONTAL),
- UsedByCtrl = create_mods_list_ctrl(Panel, Main, "Modules used by others", " and their applications"),
+ UsedByCtrl = create_mods_list_ctrl(Panel,
+ Main,
+ "Modules used by others",
+ " and their applications"),
wxSizer:add(Main,
wxStaticLine:new(Panel, [{style, ?wxLI_VERTICAL}]),
[{border, 2}, {flag, ?wxALL bor ?wxEXPAND}]),
- UsesCtrl = create_mods_list_ctrl(Panel, Main, "Used modules", " and their applications"),
+ UsesCtrl = create_mods_list_ctrl(Panel,
+ Main,
+ "Used modules",
+ " and their applications"),
S2 = S#state{deps_used_by_ctrl = UsedByCtrl,
deps_uses_ctrl = UsesCtrl},
redraw_mods(S2),
@@ -242,8 +257,10 @@ create_mods_list_ctrl(Panel, Sizer, ModText, AppText) ->
%% wxListCtrl:setColumnWidth(ListCtrl, ?MODS_APP_COL, ?MODS_APP_COL_WIDTH),
wxListItem:destroy(ListItem),
- wxEvtHandler:connect(ListCtrl, size, [{skip, true}, {userData, mods_list_ctrl}]),
- wxListCtrl:connect(ListCtrl, command_list_item_activated, [{userData, open_app}]),
+ wxEvtHandler:connect(ListCtrl, size,
+ [{skip, true}, {userData, mods_list_ctrl}]),
+ wxListCtrl:connect(ListCtrl, command_list_item_activated,
+ [{userData, open_app}]),
wxWindow:connect(ListCtrl, enter_window),
wxSizer:add(Sizer, ListCtrl,
@@ -252,7 +269,8 @@ create_mods_list_ctrl(Panel, Sizer, ModText, AppText) ->
{proportion, 1}]),
ListCtrl.
-create_code_page(#state{book = Book, code_pages = Pages, name = ModStr} = S, PageName) ->
+create_code_page(#state{book = Book, code_pages = Pages, name = ModStr} = S,
+ PageName) ->
case find_page(S, PageName) of
not_found ->
Page = do_create_code_page(S, PageName),
@@ -260,7 +278,7 @@ create_code_page(#state{book = Book, code_pages = Pages, name = ModStr} = S, Pag
Pos = length(Pages2),
wxNotebook:setSelection(Book, Pos),
case find_page(S, ?INITIAL_CODE_PAGE_NAME) of
- not_found ->
+ not_found ->
ignore;
{found, _, CodePos} ->
%% Rename initial code page
@@ -288,25 +306,29 @@ find_page([], _PageName, _Pos) ->
do_create_code_page(#state{xref_pid = Xref, mod = M} = S, PageName) ->
Panel = wxPanel:new(S#state.book, []),
Editor = create_editor(Panel),
- ToolTip = "Double click on a function call to search the function definition.",
+ ToolTip = "Double click on a function call to "
+ "search the function definition.",
wxBitmapButton:setToolTip(Editor, ToolTip),
{Objs, Data, SearchSz} = create_search_area(Panel),
{ok, App} = reltool_server:get_app(Xref, M#mod.app_name),
- ErlBin =
+ ErlBin =
case App#app.is_escript of
true -> find_escript_bin(App, M);
false -> find_regular_bin(App, M)
end,
-
+
load_code(Editor, ErlBin),
-
+
Sizer = wxBoxSizer:new(?wxVERTICAL),
wxSizer:add(Sizer, Editor, [{flag, ?wxEXPAND}, {proportion, 1}]),
wxSizer:add(Sizer, SearchSz, [{flag, ?wxEXPAND}]),
wxPanel:setSizer(Panel, Sizer),
wxNotebook:addPage(S#state.book, Panel, PageName, []),
- #code_page{name = PageName, editor = Editor, find_objs = Objs, find_data = Data}.
+ #code_page{name = PageName,
+ editor = Editor,
+ find_objs = Objs,
+ find_data = Data}.
find_regular_bin(App, Mod) ->
ActiveDir = App#app.active_dir,
@@ -322,9 +344,11 @@ find_regular_bin(App, Mod) ->
BeamFile = filename:join([ActiveDir, "ebin", ModStr ++ ".beam"]),
case beam_lib:chunks(BeamFile, [abstract_code]) of
{ok,{_,[{abstract_code,{_,AC}}]}} ->
- list_to_binary(erl_prettypr:format(erl_syntax:form_list(AC)));
+ IoList = erl_prettypr:format(erl_syntax:form_list(AC)),
+ list_to_binary(IoList);
_ ->
- list_to_binary(["%% Bad luck, cannot find any debug info in the file \"", BeamFile])
+ list_to_binary(["%% Bad luck, cannot find any "
+ "debug info in the file \"", BeamFile])
end
end.
@@ -340,10 +364,17 @@ find_escript_bin(#app{active_dir = ActiveDir}, Mod) ->
[_] ->
Bin = GetBin(),
case beam_lib:version(Bin) of
- {ok,{M, _}} when M =:= ModName; FullName =:= "." ->
- case beam_lib:chunks(Bin, [abstract_code]) of
+ {ok,{M, _}} when M =:= ModName;
+ FullName =:= "." ->
+ case beam_lib:chunks(Bin,
+ [abstract_code]) of
{ok,{_,[{abstract_code,{_,AC}}]}} ->
- {obj, list_to_binary(erl_prettypr:format(erl_syntax:form_list(AC)))};
+ Form =
+ erl_syntax:form_list(AC),
+ IoList =
+ erl_prettypr:format(Form),
+ {obj,
+ list_to_binary(IoList)};
_ ->
Acc
end;
@@ -363,10 +394,14 @@ find_escript_bin(#app{active_dir = ActiveDir}, Mod) ->
{fun(FullName, _GetInfo, GetBin, Acc) ->
io:format("", []),
case filename:split(FullName) of
- [_AppName, "ebin", F] when F =:= ObjFile, Acc =:= NotFound ->
- case beam_lib:chunks(GetBin(), [abstract_code]) of
+ [_AppName, "ebin", F]
+ when F =:= ObjFile, Acc =:= NotFound ->
+ case beam_lib:chunks(GetBin(),
+ [abstract_code]) of
{ok,{_,[{abstract_code,{_,AC}}]}} ->
- {obj, list_to_binary(erl_prettypr:format(erl_syntax:form_list(AC)))};
+ Form = erl_syntax:form_list(AC),
+ IoList = erl_prettypr:format(Form),
+ {obj, list_to_binary(IoList)};
_ ->
Acc
end;
@@ -379,17 +414,19 @@ find_escript_bin(#app{active_dir = ActiveDir}, Mod) ->
filename:dirname(ActiveDir)}
end,
try
- case escript:foldl(Fun, NotFound, Escript) of
+ case reltool_utils:escript_foldl(Fun, NotFound, Escript) of
{ok, {text, Bin}} ->
Bin;
{ok, {obj, Bin}} ->
Bin;
_ ->
- list_to_binary(["%% Bad luck, cannot find the code in the escript ", Escript, "."])
+ list_to_binary(["%% Bad luck, cannot find the "
+ "code in the escript ", Escript, "."])
end
- catch
+ catch
throw:Reason when is_list(Reason) ->
- list_to_binary(["%% Bad luck, cannot find the code in the escript ", Escript, ": ", Reason])
+ list_to_binary(["%% Bad luck, cannot find the code "
+ "in the escript ", Escript, ": ", Reason])
end.
create_config_page(S) ->
@@ -400,13 +437,16 @@ create_config_page(S) ->
handle_event(#state{xref_pid = Xref} = S, Wx) ->
%% io:format("wx: ~p\n", [Wx]),
case Wx of
- #wx{obj= ListCtrl, userData = mods_list_ctrl, event = #wxSize{type = size, size = {W, _H}}} ->
+ #wx{obj= ListCtrl,
+ userData = mods_list_ctrl,
+ event = #wxSize{type = size, size = {W, _H}}} ->
wxListCtrl:setColumnWidth(ListCtrl, ?MODS_MOD_COL, (2 * W) div 3),
wxListCtrl:setColumnWidth(ListCtrl, ?MODS_APP_COL, W div 3),
S;
#wx{userData = open_app,
obj = ListCtrl,
- event = #wxList{type = command_list_item_activated, itemIndex = Pos}} ->
+ event = #wxList{type = command_list_item_activated,
+ itemIndex = Pos}} ->
ModStr = wxListCtrl:getItemText(ListCtrl, Pos),
ModName = list_to_atom(ModStr),
{ok, Mod} = reltool_server:get_mod(Xref, ModName),
@@ -431,13 +471,15 @@ handle_event(#state{xref_pid = Xref} = S, Wx) ->
Page = lists:nth(N, S#state.code_pages),
S#state{active_page = Page}
end;
- #wx{event = #wxCommand{type = command_button_clicked}, userData = history_back} ->
+ #wx{event = #wxCommand{type = command_button_clicked},
+ userData = history_back} ->
goto_back(S);
#wx{obj = ObjRef, event = #wxMouse{type = enter_window}} ->
wxWindow:setFocus(ObjRef),
S;
_ ->
- error_logger:format("~p~p got unexpected mod event from wx:\n\t~p\n",
+ error_logger:format("~p~p got unexpected mod event from "
+ "wx:\n\t~p\n",
[?MODULE, self(), Wx]),
S
end.
@@ -450,7 +492,7 @@ redraw_mods(#state{xref_pid = Xref,
uses_mods = UsesModNames,
used_by_mods = UsedByModNames},
status_bar = Bar}) ->
- InclStatus =
+ InclStatus =
case IsIncl of
true when IsPre =:= true -> "Whitelist - ";
true -> "Derived - ";
@@ -458,8 +500,10 @@ redraw_mods(#state{xref_pid = Xref,
undefined -> "Source - "
end,
Status = lists:concat([InclStatus,
- " uses ", length(UsesModNames), " modules and ",
- " is used by ", length(UsedByModNames), " modules."]),
+ " uses ", length(UsesModNames),
+ " modules and ",
+ " is used by ", length(UsedByModNames),
+ " modules."]),
wxStatusBar:setStatusText(Bar, Status),
UsesMods = [select_image(Xref, M) || M <- UsesModNames],
UsedByMods = [select_image(Xref, M) || M <- UsedByModNames],
@@ -483,9 +527,11 @@ redraw_mods(ListCtrl, ImageMods) ->
wxListCtrl:deleteAllItems(ListCtrl),
Add =
fun({ImageId, AppName, #mod{name = ModName}}, Row) ->
- wxListCtrl:insertItem(ListCtrl, Row, ""),
- if (Row rem 2) =:= 0 ->
- wxListCtrl:setItemBackgroundColour(ListCtrl, Row, {240,240,255});
+ wxListCtrl:insertItem(ListCtrl, Row, ""),
+ if (Row rem 2) =:= 0 ->
+ wxListCtrl:setItemBackgroundColour(ListCtrl,
+ Row,
+ {240,240,255});
true ->
ignore
end,
@@ -515,16 +561,16 @@ goto_line(#state{active_page = P} = S, LineNo) when is_integer(LineNo) ->
wxStyledTextCtrl:setSelection(Editor, Left, Right),
S;
goto_line(#state{active_page = P} =S, Str) when is_list(Str) ->
- try
+ try
LineNo = list_to_integer(Str),
CurrentPos = wxStyledTextCtrl:getCurrentPos(P#code_page.editor),
S2 = add_pos_to_history(S, CurrentPos),
goto_line(S2, LineNo - 1)
- catch
+ catch
_:_ ->
wxStatusBar:setStatusText(S#state.status_bar, "Not a line number"),
S
- end.
+ end.
find_string(S, Str) ->
find_string(S, Str, 0).
@@ -535,19 +581,20 @@ find_regexp_forward(S, Str) ->
wxTextCtrl:setValue(TextCtrl, Str),
S2.
-find_string(#state{active_page = #code_page{editor = Editor,
- find_objs = #find_objs{radio={NextO,_,CaseO}},
- find_data = #find_data{found = Found} = Data} = P} = S,
+find_string(#state{active_page =
+ #code_page{editor = Editor,
+ find_objs = #find_objs{radio={NextO,_,CaseO}},
+ find_data = #find_data{found = Found} = Data} = P} = S,
Str,
Flag) ->
wxStyledTextCtrl:hideSelection(Editor, true),
Dir = wxRadioButton:getValue(NextO) xor wx_misc:getKeyState(?WXK_SHIFT),
Case = wxCheckBox:getValue(CaseO),
Pos =
- if
+ if
Found, Dir -> %% Forward Continuation
wxStyledTextCtrl:getAnchor(Editor);
- Found -> %% Backward Continuation
+ Found -> %% Backward Continuation
wxStyledTextCtrl:getCurrentPos(Editor);
Dir -> %% Forward wrap
0;
@@ -556,18 +603,18 @@ find_string(#state{active_page = #code_page{editor = Editor,
end,
wxStyledTextCtrl:gotoPos(Editor,Pos),
wxStyledTextCtrl:searchAnchor(Editor),
- Flag2 =
+ Flag2 =
if Case -> Flag bor ?wxSTC_FIND_MATCHCASE;
true -> Flag
end,
- Res =
- if
+ Res =
+ if
Dir -> wxStyledTextCtrl:searchNext(Editor, Flag2, Str);
true -> wxStyledTextCtrl:searchPrev(Editor, Flag2, Str)
end,
- Found2 =
+ Found2 =
case Res >= 0 of
- true ->
+ true ->
wxStyledTextCtrl:hideSelection(Editor, false),
%% io:format("Found ~p ~n",[Res]),
LineNo = wxStyledTextCtrl:lineFromPosition(Editor,Res),
@@ -576,11 +623,15 @@ find_string(#state{active_page = #code_page{editor = Editor,
true;
false ->
wxStatusBar:setStatusText(S#state.status_bar,
- "Not found (Hit Enter to wrap search)"),
+ "Not found (Hit Enter to "
+ "wrap search)"),
false
- end,
+ end,
P2 = P#code_page{find_data = Data#find_data{found = Found2}},
- Pages = lists:keystore(P#code_page.name, #code_page.name, S#state.code_pages, P2),
+ Pages = lists:keystore(P#code_page.name,
+ #code_page.name,
+ S#state.code_pages,
+ P2),
S#state{active_page = P2, code_pages = Pages}.
goto_function(S, Editor) ->
@@ -589,14 +640,14 @@ goto_function(S, Editor) ->
Left = wxStyledTextCtrl:wordStartPosition(Editor, CurrentPos, true),
Right = wxStyledTextCtrl:wordEndPosition(Editor, CurrentPos, true),
ColonPos = Left - 1,
- Left2 =
+ Left2 =
case wxStyledTextCtrl:getCharAt(Editor, ColonPos) of
$: ->
wxStyledTextCtrl:wordStartPosition(Editor, ColonPos, true);
_ ->
Left
end,
- Right2 =
+ Right2 =
case wxStyledTextCtrl:getCharAt(Editor, Right) of
$: ->
wxStyledTextCtrl:wordEndPosition(Editor, Right + 1, true);
@@ -627,29 +678,37 @@ do_goto_function(S, [ModStr, FunStr]) ->
S2 = create_code_page(S#state{mod = Mod}, ModStr),
find_regexp_forward(S2, "^" ++ FunStr ++ "(");
{ok, _} ->
- wxStatusBar:setStatusText(S#state.status_bar, "No such module: " ++ ModStr),
+ wxStatusBar:setStatusText(S#state.status_bar,
+ "No such module: " ++ ModStr),
S
end.
-goto_back(#state{active_page = #code_page{editor = Editor, find_data = Data} = Page,
+goto_back(#state{active_page =
+ #code_page{editor = Editor, find_data = Data} = Page,
code_pages = Pages} = S) ->
case Data#find_data.history of
[PrevPos | History] ->
LineNo = wxStyledTextCtrl:lineFromPosition(Editor, PrevPos),
Data2 = Data#find_data{history = History},
Page2 = Page#code_page{find_data = Data2},
- Pages2 = lists:keystore(Page2#code_page.name, #code_page.name, Pages, Page2),
- goto_line(S#state{active_page = Page2, code_pages = Pages2}, LineNo);
+ Pages2 = lists:keystore(Page2#code_page.name,
+ #code_page.name,
+ Pages,
+ Page2),
+ goto_line(S#state{active_page = Page2, code_pages = Pages2},
+ LineNo);
[] ->
wxStatusBar:setStatusText(S#state.status_bar, "No history"),
S
end.
-add_pos_to_history(#state{active_page = Page, code_pages = Pages} = S, CurrentPos) ->
+add_pos_to_history(#state{active_page = Page, code_pages = Pages} = S,
+ CurrentPos) ->
Data = Page#code_page.find_data,
Data2 = Data#find_data{history = [CurrentPos | Data#find_data.history]},
Page2 = Page#code_page{find_data = Data2},
- Pages2 = lists:keystore(Page2#code_page.name, #code_page.name, Pages, Page2),
+ Pages2 =
+ lists:keystore(Page2#code_page.name, #code_page.name, Pages, Page2),
S#state{active_page = Page2, code_pages = Pages2}.
create_editor(Parent) ->
@@ -690,19 +749,26 @@ create_editor(Parent) ->
%% Margins Markers
%% Breakpoint Should be a pixmap?
- wxStyledTextCtrl:markerDefine(Ed, 0, ?wxSTC_MARK_CIRCLE, [{foreground, {170,20,20}}]),
- wxStyledTextCtrl:markerDefine(Ed, 0, ?wxSTC_MARK_CIRCLE, [{background, {200,120,120}}]),
- %% Disabled Breakpoint
- wxStyledTextCtrl:markerDefine(Ed, 1, ?wxSTC_MARK_CIRCLE, [{foreground, {20,20,170}}]),
- wxStyledTextCtrl:markerDefine(Ed, 1, ?wxSTC_MARK_CIRCLE, [{background, {120,120,200}}]),
-
+ wxStyledTextCtrl:markerDefine(Ed, 0, ?wxSTC_MARK_CIRCLE,
+ [{foreground, {170,20,20}}]),
+ wxStyledTextCtrl:markerDefine(Ed, 0, ?wxSTC_MARK_CIRCLE,
+ [{background, {200,120,120}}]),
+ %% Disabled Breakpoint
+ wxStyledTextCtrl:markerDefine(Ed, 1, ?wxSTC_MARK_CIRCLE,
+ [{foreground, {20,20,170}}]),
+ wxStyledTextCtrl:markerDefine(Ed, 1, ?wxSTC_MARK_CIRCLE,
+ [{background, {120,120,200}}]),
+
%% Current Line
- wxStyledTextCtrl:markerDefine(Ed, 2, ?wxSTC_MARK_ARROW, [{foreground, {20,170,20}}]),
- wxStyledTextCtrl:markerDefine(Ed, 2, ?wxSTC_MARK_ARROW, [{background, {200,255,200}}]),
- wxStyledTextCtrl:markerDefine(Ed, 3, ?wxSTC_MARK_BACKGROUND, [{background, {200,255,200}}]),
+ wxStyledTextCtrl:markerDefine(Ed, 2, ?wxSTC_MARK_ARROW,
+ [{foreground, {20,170,20}}]),
+ wxStyledTextCtrl:markerDefine(Ed, 2, ?wxSTC_MARK_ARROW,
+ [{background, {200,255,200}}]),
+ wxStyledTextCtrl:markerDefine(Ed, 3, ?wxSTC_MARK_BACKGROUND,
+ [{background, {200,255,200}}]),
%% Scrolling
- Policy = ?wxSTC_CARET_SLOP bor ?wxSTC_CARET_JUMPS bor ?wxSTC_CARET_EVEN,
+ Policy = ?wxSTC_CARET_SLOP bor ?wxSTC_CARET_JUMPS bor ?wxSTC_CARET_EVEN,
wxStyledTextCtrl:setYCaretPolicy(Ed, Policy, 3),
wxStyledTextCtrl:setVisiblePolicy(Ed, Policy, 3),
@@ -714,9 +780,9 @@ create_editor(Parent) ->
create_search_area(Parent) ->
Sizer = wxBoxSizer:new(?wxHORIZONTAL),
- wxSizer:add(Sizer, wxStaticText:new(Parent, ?wxID_ANY, "Find:"),
+ wxSizer:add(Sizer, wxStaticText:new(Parent, ?wxID_ANY, "Find:"),
[{flag,?wxALIGN_CENTER_VERTICAL}]),
- TC1 = wxTextCtrl:new(Parent, ?SEARCH_ENTRY, [{style, ?wxTE_PROCESS_ENTER}]),
+ TC1 = wxTextCtrl:new(Parent, ?SEARCH_ENTRY, [{style, ?wxTE_PROCESS_ENTER}]),
wxSizer:add(Sizer, TC1, [{proportion,3}, {flag, ?wxEXPAND}]),
Nbtn = wxRadioButton:new(Parent, ?wxID_ANY, "Next"),
wxRadioButton:setValue(Nbtn, true),
@@ -726,14 +792,15 @@ create_search_area(Parent) ->
Cbtn = wxCheckBox:new(Parent, ?wxID_ANY, "Match Case"),
wxSizer:add(Sizer,Cbtn,[{flag,?wxALIGN_CENTER_VERTICAL}]),
wxSizer:add(Sizer, 15,15, [{proportion,1}, {flag, ?wxEXPAND}]),
- wxSizer:add(Sizer, wxStaticText:new(Parent, ?wxID_ANY, "Goto Line:"),
+ wxSizer:add(Sizer, wxStaticText:new(Parent, ?wxID_ANY, "Goto Line:"),
[{flag,?wxALIGN_CENTER_VERTICAL}]),
- TC2 = wxTextCtrl:new(Parent, ?GOTO_ENTRY, [{style, ?wxTE_PROCESS_ENTER}]),
+ TC2 = wxTextCtrl:new(Parent, ?GOTO_ENTRY, [{style, ?wxTE_PROCESS_ENTER}]),
wxSizer:add(Sizer, TC2, [{proportion,0}, {flag, ?wxEXPAND}]),
Button = wxButton:new(Parent, ?wxID_ANY, [{label, "Back"}]),
wxSizer:add(Sizer, Button, []),
- wxEvtHandler:connect(Button, command_button_clicked, [{userData, history_back}]),
+ wxEvtHandler:connect(Button, command_button_clicked,
+ [{userData, history_back}]),
%% wxTextCtrl:connect(TC1, command_text_updated),
wxTextCtrl:connect(TC1, command_text_enter),
%% wxTextCtrl:connect(TC1, kill_focus),
@@ -748,7 +815,9 @@ load_code(Ed, Code) when is_binary(Code) ->
wxStyledTextCtrl:setTextRaw(Ed, <<Code/binary, 0:8>>),
Lines = wxStyledTextCtrl:getLineCount(Ed),
Sz = trunc(math:log10(Lines))+1,
- LW = wxStyledTextCtrl:textWidth(Ed, ?wxSTC_STYLE_LINENUMBER, lists:duplicate(Sz, $9)),
+ LW = wxStyledTextCtrl:textWidth(Ed,
+ ?wxSTC_STYLE_LINENUMBER,
+ lists:duplicate(Sz, $9)),
%%io:format("~p ~p ~p~n", [Lines, Sz, LW]),
wxStyledTextCtrl:setMarginWidth(Ed, 0, LW+5),
wxStyledTextCtrl:setReadOnly(Ed, true),
diff --git a/lib/reltool/src/reltool_server.erl b/lib/reltool/src/reltool_server.erl
index 8d4530131f..a7064f7651 100644
--- a/lib/reltool/src/reltool_server.erl
+++ b/lib/reltool/src/reltool_server.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
-module(reltool_server).
@@ -44,7 +44,7 @@
-include("reltool.hrl").
--record(state,
+-record(state,
{options,
parent_pid,
common,
@@ -60,16 +60,20 @@ start_link() ->
start_link([]).
start_link(Options) ->
- proc_lib:start_link(?MODULE, init, [[{parent, self()} | Options]], infinity, []).
+ proc_lib:start_link(?MODULE,
+ init,
+ [[{parent, self()} | Options]],
+ infinity,
+ []).
-get_config(Pid, InclDefaults, InclDerivates) ->
- reltool_utils:call(Pid, {get_config, InclDefaults, InclDerivates}).
+get_config(Pid, InclDef, InclDeriv) ->
+ reltool_utils:call(Pid, {get_config, InclDef, InclDeriv}).
load_config(Pid, FilenameOrConfig) ->
reltool_utils:call(Pid, {load_config, FilenameOrConfig}).
-save_config(Pid, Filename, InclDefaults, InclDerivates) ->
- reltool_utils:call(Pid, {save_config, Filename, InclDefaults, InclDerivates}).
+save_config(Pid, Filename, InclDef, InclDeriv) ->
+ reltool_utils:call(Pid, {save_config, Filename, InclDef, InclDeriv}).
reset_config(Pid) ->
reltool_utils:call(Pid, reset_config).
@@ -131,7 +135,8 @@ do_init(Options) ->
case parse_options(Options) of
{#state{parent_pid = ParentPid, common = C, sys = Sys} = S, Status} ->
%% process_flag(trap_exit, (S#state.common)#common.trap_exit),
- proc_lib:init_ack(ParentPid, {ok, self(), C, Sys#sys{apps = undefined}}),
+ proc_lib:init_ack(ParentPid,
+ {ok, self(), C, Sys#sys{apps = undefined}}),
{S2, Status2} = refresh(S, true, Status),
{S3, Status3} = analyse(S2#state{old_sys = S2#state.sys}, Status2),
case Status3 of
@@ -156,15 +161,33 @@ parse_options(Opts) ->
rels = reltool_utils:default_rels(),
emu_name = ?DEFAULT_EMU_NAME,
profile = ?DEFAULT_PROFILE,
- incl_sys_filters = reltool_utils:decode_regexps(incl_sys_filters, ?DEFAULT_INCL_SYS_FILTERS, []),
- excl_sys_filters = reltool_utils:decode_regexps(excl_sys_filters, ?DEFAULT_EXCL_SYS_FILTERS, []),
- incl_app_filters = reltool_utils:decode_regexps(incl_app_filters, ?DEFAULT_INCL_APP_FILTERS, []),
- excl_app_filters = reltool_utils:decode_regexps(excl_app_filters, ?DEFAULT_EXCL_APP_FILTERS, []),
+ incl_sys_filters =
+ reltool_utils:decode_regexps(incl_sys_filters,
+ ?DEFAULT_INCL_SYS_FILTERS,
+ []),
+ excl_sys_filters =
+ reltool_utils:decode_regexps(excl_sys_filters,
+ ?DEFAULT_EXCL_SYS_FILTERS,
+ []),
+ incl_app_filters =
+ reltool_utils:decode_regexps(incl_app_filters,
+ ?DEFAULT_INCL_APP_FILTERS,
+ []),
+ excl_app_filters =
+ reltool_utils:decode_regexps(excl_app_filters,
+ ?DEFAULT_EXCL_APP_FILTERS,
+ []),
relocatable = ?DEFAULT_RELOCATABLE,
app_type = ?DEFAULT_APP_TYPE,
app_file = ?DEFAULT_APP_FILE,
- incl_archive_filters = reltool_utils:decode_regexps(incl_archive_filters, ?DEFAULT_INCL_ARCHIVE_FILTERS, []),
- excl_archive_filters = reltool_utils:decode_regexps(excl_archive_filters, ?DEFAULT_EXCL_ARCHIVE_FILTERS, []),
+ incl_archive_filters =
+ reltool_utils:decode_regexps(incl_archive_filters,
+ ?DEFAULT_INCL_ARCHIVE_FILTERS,
+ []),
+ excl_archive_filters =
+ reltool_utils:decode_regexps(excl_archive_filters,
+ ?DEFAULT_EXCL_ARCHIVE_FILTERS,
+ []),
archive_opts = ?DEFAULT_ARCHIVE_OPTS,
debug_info = ?DEFAULT_DEBUG_INFO},
C2 = #common{sys_debug = [],
@@ -194,30 +217,38 @@ parse_options([{Key, Val} | KeyVals], S, C, Sys, Status) ->
parse_options(KeyVals, S, C, Sys2, Status2);
_ ->
Text = lists:flatten(io_lib:format("~p", [{Key, Val}])),
- Status2 = reltool_utils:return_first_error(Status, "Illegal option: " ++ Text),
+ Status2 =
+ reltool_utils:return_first_error(Status,
+ "Illegal option: " ++ Text),
parse_options(KeyVals, S, C, Sys, Status2)
end;
parse_options([], S, C, Sys, Status) ->
{S#state{common = C, sys = Sys}, Status};
parse_options(KeyVals, S, C, Sys, Status) ->
Text = lists:flatten(io_lib:format("~p", [KeyVals])),
- Status2 = reltool_utils:return_first_error(Status, "Illegal options: " ++ Text),
+ Status2 = reltool_utils:return_first_error(Status,
+ "Illegal options: " ++ Text),
{S#state{common = C, sys = Sys}, Status2}.
loop(#state{common = C, sys = Sys} = S) ->
receive
{system, From, Msg} ->
- sys:handle_system_msg(Msg, From, S#state.parent_pid, ?MODULE, C#common.sys_debug, S);
- {call, ReplyTo, Ref, {get_config, InclDefaults, InclDerivates}} ->
- Reply = do_get_config(S, InclDefaults, InclDerivates),
+ sys:handle_system_msg(Msg,
+ From,
+ S#state.parent_pid,
+ ?MODULE,
+ C#common.sys_debug,
+ S);
+ {call, ReplyTo, Ref, {get_config, InclDef, InclDeriv}} ->
+ Reply = do_get_config(S, InclDef, InclDeriv),
reltool_utils:reply(ReplyTo, Ref, Reply),
?MODULE:loop(S);
{call, ReplyTo, Ref, {load_config, SysConfig}} ->
{S2, Reply} = do_load_config(S, SysConfig),
reltool_utils:reply(ReplyTo, Ref, Reply),
?MODULE:loop(S2);
- {call, ReplyTo, Ref, {save_config, Filename, InclDefaults, InclDerivates}} ->
- Reply = do_save_config(S, Filename, InclDefaults, InclDerivates),
+ {call, ReplyTo, Ref, {save_config, Filename, InclDef, InclDeriv}} ->
+ Reply = do_save_config(S, Filename, InclDef, InclDeriv),
reltool_utils:reply(ReplyTo, Ref, Reply),
?MODULE:loop(S);
{call, ReplyTo, Ref, reset_config} ->
@@ -225,7 +256,7 @@ loop(#state{common = C, sys = Sys} = S) ->
S3 = shrink_sys(S2),
{S4, Status2} = refresh(S3, true, Status),
{S5, Status3} = analyse(S4#state{old_sys = S4#state.sys}, Status2),
- S6 =
+ S6 =
case Status3 of
{ok, _Warnings} ->
S5#state{status = Status3, old_status = S#state.status};
@@ -236,14 +267,14 @@ loop(#state{common = C, sys = Sys} = S) ->
?MODULE:loop(S6);
{call, ReplyTo, Ref, undo_config} ->
reltool_utils:reply(ReplyTo, Ref, ok),
- S2 = S#state{sys = S#state.old_sys,
+ S2 = S#state{sys = S#state.old_sys,
old_sys = S#state.sys,
status = S#state.old_status,
old_status = S#state.status},
?MODULE:loop(S2);
{call, ReplyTo, Ref, {get_rel, RelName}} ->
Sys = S#state.sys,
- Reply =
+ Reply =
case lists:keysearch(RelName, #rel.name, Sys#sys.rels) of
{value, Rel} ->
{ok, reltool_target:gen_rel(Rel, Sys)};
@@ -254,12 +285,12 @@ loop(#state{common = C, sys = Sys} = S) ->
?MODULE:loop(S);
{call, ReplyTo, Ref, {get_script, RelName}} ->
Sys = S#state.sys,
- Reply =
+ Reply =
case lists:keysearch(RelName, #rel.name, Sys#sys.rels) of
{value, Rel} ->
PathFlag = true,
- Variables = [],
- reltool_target:gen_script(Rel, Sys, PathFlag, Variables);
+ Vars = [],
+ reltool_target:gen_script(Rel, Sys, PathFlag, Vars);
false ->
{error, "No such release"}
end,
@@ -276,7 +307,7 @@ loop(#state{common = C, sys = Sys} = S) ->
reltool_utils:reply(ReplyTo, Ref, Reply),
?MODULE:loop(S);
{call, ReplyTo, Ref, {get_app, AppName}} when is_atom(AppName) ->
- Reply =
+ Reply =
case lists:keysearch(AppName, #app.name, Sys#sys.apps) of
{value, App} ->
{ok, App};
@@ -302,15 +333,15 @@ loop(#state{common = C, sys = Sys} = S) ->
{call, ReplyTo, Ref, {get_apps, Kind}} ->
AppNames =
case Kind of
- whitelist ->
+ whitelist ->
[A ||
A <- Sys#sys.apps,
A#app.is_pre_included =:= true];
- blacklist ->
+ blacklist ->
[A ||
A <- Sys#sys.apps,
A#app.is_pre_included =:= false];
- source ->
+ source ->
[A ||
A <- Sys#sys.apps,
A#app.is_included =/= true,
@@ -324,9 +355,10 @@ loop(#state{common = C, sys = Sys} = S) ->
reltool_utils:reply(ReplyTo, Ref, {ok, AppNames}),
?MODULE:loop(S);
{call, ReplyTo, Ref, {set_apps, Apps}} ->
- {S2, Status} = lists:foldl(fun(A, {X, Y}) -> do_set_app(X, A, Y) end,
- {S, {ok, []}},
- Apps),
+ {S2, Status} =
+ lists:foldl(fun(A, {X, Y}) -> do_set_app(X, A, Y) end,
+ {S, {ok, []}},
+ Apps),
{S3, Status2} = analyse(S2, Status),
reltool_utils:reply(ReplyTo, Ref, Status2),
?MODULE:loop(S3);
@@ -335,13 +367,13 @@ loop(#state{common = C, sys = Sys} = S) ->
?MODULE:loop(S);
{call, ReplyTo, Ref, {set_sys, Sys2}} ->
S2 = S#state{sys = Sys2#sys{apps = Sys#sys.apps}},
- Force =
+ Force =
(Sys2#sys.root_dir =/= Sys#sys.root_dir) orelse
(Sys2#sys.lib_dirs =/= Sys#sys.lib_dirs) orelse
(Sys2#sys.escripts =/= Sys#sys.escripts),
{S3, Status} = refresh(S2, Force, {ok, []}),
{S4, Status2} = analyse(S3#state{old_sys = S#state.sys}, Status),
- S6 =
+ S6 =
case Status2 of
{ok, _Warnings} ->
S4#state{status = Status2, old_status = S#state.status};
@@ -354,7 +386,7 @@ loop(#state{common = C, sys = Sys} = S) ->
reltool_utils:reply(ReplyTo, Ref, S#state.status),
?MODULE:loop(S);
{call, ReplyTo, Ref, {gen_rel_files, Dir}} ->
- Status =
+ Status =
case reltool_target:gen_rel_files(S#state.sys, Dir) of
ok ->
{ok, []};
@@ -404,7 +436,7 @@ analyse(#state{common = C, sys = #sys{apps = Apps0} = Sys} = S, Status) ->
ets:insert(C#common.app_tab, MissingApp),
Apps2 = lists:map(fun(App) -> app_init_is_included(C, Sys, App) end, Apps),
- Apps3 =
+ Apps3 =
case app_propagate_is_included(C, Sys, Apps2, []) of
[] ->
Apps2;
@@ -412,14 +444,15 @@ analyse(#state{common = C, sys = #sys{apps = Apps0} = Sys} = S, Status) ->
%% io:format("Missing mods: ~p\n", [MissingMods]),
MissingApp2 = MissingApp#app{label = ?MISSING_APP_TEXT,
info = missing_app_info(""),
- mods = MissingMods,
+ mods = MissingMods,
status = missing,
uses_mods = []},
[MissingApp2 | Apps2]
end,
app_propagate_is_used_by(C, Apps3),
Apps4 = read_apps(C, Sys, Apps3, []),
- %% io:format("Missing app: ~p\n", [lists:keysearch(?MISSING_APP, #app.name, Apps4)]),
+ %% io:format("Missing app: ~p\n",
+ %% [lists:keysearch(?MISSING_APP, #app.name, Apps4)]),
Sys2 = Sys#sys{apps = Apps4},
try
Status2 = verify_config(Sys2, Status),
@@ -430,7 +463,7 @@ analyse(#state{common = C, sys = #sys{apps = Apps0} = Sys} = S, Status) ->
end.
app_init_is_included(C, Sys, #app{mods = Mods} = A) ->
- AppCond =
+ AppCond =
case A#app.incl_cond of
undefined -> Sys#sys.incl_cond;
_ -> A#app.incl_cond
@@ -448,7 +481,14 @@ app_init_is_included(C, Sys, #app{mods = Mods} = A) ->
end,
A2 = A#app{is_pre_included = IsIncl, is_included = IsIncl},
ets:insert(C#common.app_tab, A2),
- lists:foreach(fun(Mod) -> mod_init_is_included(C, Mod, ModCond, AppCond, undefined) end, Mods),
+ lists:foreach(fun(Mod) ->
+ mod_init_is_included(C,
+ Mod,
+ ModCond,
+ AppCond,
+ undefined)
+ end,
+ Mods),
%%app_mod_init_is_included(C, AppName, Info, ModCond, AppCond),
A2.
@@ -463,7 +503,8 @@ mod_init_is_included(C, M, ModCond, AppCond, Default) ->
exclude ->
false;
undefined ->
- %% print(M#mod.name, hipe, "mod_cond -> ~p\n", [ModCond]),
+ %% print(M#mod.name, hipe, "mod_cond -> ~p\n",
+ %% [ModCond]),
case ModCond of
all -> true;
app -> false_to_undefined(M#mod.is_app_mod);
@@ -493,7 +534,7 @@ false_to_undefined(Bool) ->
false -> undefined;
_ -> Bool
end.
-
+
app_propagate_is_included(C, Sys, [#app{mods = Mods} = A | Apps], Acc) ->
Acc2 = mod_propagate_is_included(C, Sys, A, Mods, Acc),
app_propagate_is_included(C, Sys, Apps, Acc2);
@@ -502,9 +543,11 @@ app_propagate_is_included(_C, _Sys, [], Acc) ->
mod_propagate_is_included(C, Sys, A, [#mod{name = ModName} | Mods], Acc) ->
[M2] = ets:lookup(C#common.mod_tab, ModName),
- %% print(ModName, file, "Maybe Prop ~p -> ~p\n", [M2, M2#mod.is_included]),
- %% print(ModName, filename, "Maybe Prop ~p -> ~p\n", [M2, M2#mod.is_included]),
- Acc2 =
+ %% print(ModName, file, "Maybe Prop ~p -> ~p\n",
+ %% [M2, M2#mod.is_included]),
+ %% print(ModName, filename, "Maybe Prop ~p -> ~p\n",
+ %% [M2, M2#mod.is_included]),
+ Acc2 =
case M2#mod.is_included of
true ->
%% Propagate include mark
@@ -519,11 +562,13 @@ mod_propagate_is_included(_C, _Sys, _A, [], Acc) ->
Acc.
mod_mark_is_included(C, Sys, UsedByName, [ModName | ModNames], Acc) ->
- Acc3 =
+ Acc3 =
case ets:lookup(C#common.mod_tab, ModName) of
- [M] ->
- %% print(UsedByName, file, "Maybe Mark ~p -> ~p\n", [M, M#mod.is_included]),
- %% print(UsedByName, filename, "Maybe Mark ~p -> ~p\n", [M, M#mod.is_included]),
+ [M] ->
+ %% print(UsedByName, file, "Maybe Mark ~p -> ~p\n",
+ %% [M, M#mod.is_included]),
+ %% print(UsedByName, filename, "Maybe Mark ~p -> ~p\n",
+ %% [M, M#mod.is_included]),
case M#mod.is_included of
true ->
%% Already marked
@@ -533,19 +578,22 @@ mod_mark_is_included(C, Sys, UsedByName, [ModName | ModNames], Acc) ->
Acc;
undefined ->
%% Mark and propagate
- M2 =
+ M2 =
case M#mod.incl_cond of
include ->
- M#mod{is_pre_included = true, is_included = true};
+ M#mod{is_pre_included = true,
+ is_included = true};
exclude ->
- M#mod{is_pre_included = true, is_included = true};
+ M#mod{is_pre_included = true,
+ is_included = true};
undefined ->
M#mod{is_included = true}
end,
ets:insert(C#common.mod_tab, M2),
- %% io:format("Propagate mod: ~p -> ~p (~p)\n", [UsedByName, ModName, M#mod.incl_cond]),
+ %% io:format("Propagate mod: ~p -> ~p (~p)\n",
+ %% [UsedByName, ModName, M#mod.incl_cond]),
[A] = ets:lookup(C#common.app_tab, M2#mod.app_name),
- Acc2 =
+ Acc2 =
case A#app.is_included of
true ->
Acc;
@@ -557,7 +605,7 @@ mod_mark_is_included(C, Sys, UsedByName, [ModName | ModNames], Acc) ->
undefined -> Sys#sys.mod_cond;
_ -> A#app.mod_cond
end,
- Filter =
+ Filter =
fun(M3) ->
case ModCond of
all -> true;
@@ -569,12 +617,22 @@ mod_mark_is_included(C, Sys, UsedByName, [ModName | ModNames], Acc) ->
end,
Mods = lists:filter(Filter, A#app.mods),
%% io:format("Propagate app: ~p ~p -> ~p\n",
- %% [UsedByName, A#app.name, [M3#mod.name || M3 <- Mods]]),
+ %% [UsedByName, A#app.name,
+ %% [M3#mod.name || M3 <- Mods]]),
A2 = A#app{is_included = true},
- ets:insert(C#common.app_tab, A2),
- mod_mark_is_included(C, Sys, ModName, [M3#mod.name || M3 <- Mods], Acc)
+ ets:insert(C#common.app_tab, A2),
+ mod_mark_is_included(C,
+ Sys,
+ ModName,
+ [M3#mod.name ||
+ M3 <- Mods],
+ Acc)
end,
- mod_mark_is_included(C, Sys, ModName, M2#mod.uses_mods, Acc2)
+ mod_mark_is_included(C,
+ Sys,
+ ModName,
+ M2#mod.uses_mods,
+ Acc2)
end;
[] ->
M = missing_mod(ModName, ?MISSING_APP),
@@ -614,21 +672,24 @@ mod_propagate_is_used_by(_C, []) ->
read_apps(C, Sys, [#app{mods = Mods, is_included = IsIncl} = A | Apps], Acc) ->
{Mods2, IsIncl2} = read_apps(C, Sys, A, Mods, [], IsIncl),
- %% reltool_utils:print(A#app.name, stdlib, "Mods2: ~p\n", [[M#mod.status || M <- Mods2]]),
- Status =
+ %% reltool_utils:print(A#app.name, stdlib, "Mods2: ~p\n",
+ %% [[M#mod.status || M <- Mods2]]),
+ Status =
case lists:keysearch(missing, #mod.status, Mods2) of
{value, _} -> missing;
false -> ok
end,
UsesMods = [M#mod.uses_mods || M <- Mods2, M#mod.is_included =:= true],
UsesMods2 = lists:usort(lists:flatten(UsesMods)),
- UsesApps = [M#mod.app_name || ModName <- UsesMods2, M <- ets:lookup(C#common.mod_tab, ModName)],
+ UsesApps = [M#mod.app_name || ModName <- UsesMods2,
+ M <- ets:lookup(C#common.mod_tab, ModName)],
UsesApps2 = lists:usort(UsesApps),
UsedByMods = [M#mod.used_by_mods || M <- Mods2, M#mod.is_included =:= true],
UsedByMods2 = lists:usort(lists:flatten(UsedByMods)),
- UsedByApps = [M#mod.app_name || ModName <- UsedByMods2, M <- ets:lookup(C#common.mod_tab, ModName)],
+ UsedByApps = [M#mod.app_name || ModName <- UsedByMods2,
+ M <- ets:lookup(C#common.mod_tab, ModName)],
UsedByApps2 = lists:usort(UsedByApps),
-
+
A2 = A#app{mods = Mods2,
status = Status,
uses_mods = UsesMods2,
@@ -644,12 +705,14 @@ read_apps(C, Sys, A, [#mod{name = ModName} | Mods], Acc, IsIncl) ->
[M2] = ets:lookup(C#common.mod_tab, ModName),
Status = do_get_status(M2),
%% print(M2#mod.name, hipe, "status -> ~p\n", [Status]),
- {IsIncl2, M3} =
+ {IsIncl2, M3} =
case M2#mod.is_included of
true ->
- UsedByMods = [N || {_, N} <- ets:lookup(C#common.mod_used_by_tab, ModName)],
+ UsedByMods =
+ [N || {_, N} <- ets:lookup(C#common.mod_used_by_tab,
+ ModName)],
{true, M2#mod{status = Status, used_by_mods = UsedByMods}};
- _ ->
+ _ ->
{IsIncl, M2#mod{status = Status, used_by_mods = []}}
end,
ets:insert(C#common.mod_tab, M3),
@@ -669,14 +732,14 @@ shrink_sys(#state{sys = #sys{apps = Apps} = Sys} = S) ->
Apps2 = lists:zf(fun filter_app/1, Apps),
S#state{sys = Sys#sys{apps = Apps2}}.
-filter_app(A) ->
+filter_app(A) ->
Mods = [M#mod{is_app_mod = undefined,
is_ebin_mod = undefined,
uses_mods = undefined,
exists = false,
is_pre_included = undefined,
is_included = undefined} ||
- M <- A#app.mods,
+ M <- A#app.mods,
M#mod.incl_cond =/= undefined],
if
A#app.is_escript ->
@@ -692,9 +755,9 @@ filter_app(A) ->
A#app.use_selected_vsn =:= undefined ->
false;
true ->
- {Dir, Dirs} =
+ {Dir, Dirs} =
case A#app.use_selected_vsn of
- undefined ->
+ undefined ->
{shrinked, []};
false ->
{shrinked, []};
@@ -730,37 +793,45 @@ refresh_app(#app{name = AppName,
Status) ->
if
Force; OptLabel =:= undefined ->
- {AppInfo, EbinMods, Status3} =
+ {AppInfo, EbinMods, Status3} =
case IsEscript of
false ->
-
+
%% Add info from .app file
Base = get_base(AppName, ActiveDir),
{_, DefaultVsn} = reltool_utils:split_app_name(Base),
Ebin = filename:join([ActiveDir, "ebin"]),
- AppFile = filename:join([Ebin, atom_to_list(AppName) ++ ".app"]),
- {AI, Status2} = read_app_info(AppFile, AppFile, AppName, DefaultVsn, Status),
+ AppFile =
+ filename:join([Ebin,
+ atom_to_list(AppName) ++ ".app"]),
+ {AI, Status2} =
+ read_app_info(AppFile,
+ AppFile,
+ AppName,
+ DefaultVsn,
+ Status),
{AI, read_ebin_mods(Ebin, AppName), Status2};
true ->
{App#app.info, Mods, Status}
end,
-
+
%% Add non-existing modules
AppModNames =
case AppInfo#app_info.mod of
{StartModName, _} ->
- case lists:member(StartModName, AppInfo#app_info.modules) of
+ case lists:member(StartModName,
+ AppInfo#app_info.modules) of
true -> AppInfo#app_info.modules;
false -> [StartModName | AppInfo#app_info.modules]
end;
- undefined ->
+ undefined ->
AppInfo#app_info.modules
end,
MissingMods = add_missing_mods(AppName, EbinMods, AppModNames),
-
+
%% Add optional user config for each module
Mods2 = add_mod_config(MissingMods ++ EbinMods, Mods),
-
+
%% Set app flag for each module in app file
Mods3 = set_mod_flags(Mods2, AppModNames),
AppVsn = AppInfo#app_info.vsn,
@@ -770,7 +841,7 @@ refresh_app(#app{name = AppName,
_ -> atom_to_list(AppName) ++ "-" ++ AppVsn
end,
App2 = App#app{vsn = AppVsn,
- label = AppLabel,
+ label = AppLabel,
info = AppInfo,
mods = lists:keysort(#mod.name, Mods3)},
{App2, Status3};
@@ -790,30 +861,55 @@ read_app_info(AppFileOrBin, AppFile, AppName, DefaultVsn, Status) ->
AI = #app_info{vsn = DefaultVsn},
parse_app_info(AppFile, Info, AI, Status);
{ok, _BadApp} ->
- Text = lists:concat([AppName, ": Illegal contents in app file ", AppFile]),
- {missing_app_info(DefaultVsn), reltool_utils:add_warning(Status, Text)};
+ Text = lists:concat([AppName,
+ ": Illegal contents in app file ", AppFile]),
+ {missing_app_info(DefaultVsn),
+ reltool_utils:add_warning(Status, Text)};
{error, Text} when Text =:= EnoentText->
{missing_app_info(DefaultVsn), Status};
{error, Text} ->
- Text2 = lists:concat([AppName, ": Cannot parse app file ", AppFile, " (", Text, ")."]),
- {missing_app_info(DefaultVsn), reltool_utils:add_warning(Status, Text2)}
+ Text2 = lists:concat([AppName,
+ ": Cannot parse app file ",
+ AppFile, " (", Text, ")."]),
+ {missing_app_info(DefaultVsn),
+ reltool_utils:add_warning(Status, Text2)}
end.
parse_app_info(File, [{Key, Val} | KeyVals], AI, Status) ->
case Key of
- description -> parse_app_info(File, KeyVals, AI#app_info{description = Val}, Status);
- id -> parse_app_info(File, KeyVals, AI#app_info{id = Val}, Status);
- vsn -> parse_app_info(File, KeyVals, AI#app_info{vsn = Val}, Status);
- modules -> parse_app_info(File, KeyVals, AI#app_info{modules = Val}, Status);
- maxP -> parse_app_info(File, KeyVals, AI#app_info{maxP = Val}, Status);
- maxT -> parse_app_info(File, KeyVals, AI#app_info{maxT = Val}, Status);
- registered -> parse_app_info(File, KeyVals, AI#app_info{registered = Val}, Status);
- included_applications -> parse_app_info(File, KeyVals, AI#app_info{incl_apps = Val}, Status);
- applications -> parse_app_info(File, KeyVals, AI#app_info{applications = Val}, Status);
- env -> parse_app_info(File, KeyVals, AI#app_info{env = Val}, Status);
- mod -> parse_app_info(File, KeyVals, AI#app_info{mod = Val}, Status);
- start_phases -> parse_app_info(File, KeyVals, AI#app_info{start_phases = Val}, Status);
- _ -> parse_app_info(File, KeyVals, AI, reltool_utils:add_warning(Status, lists:concat(["Unexpected item ", Key, "in app file ", File])))
+ description ->
+ parse_app_info(File, KeyVals, AI#app_info{description = Val},
+ Status);
+ id ->
+ parse_app_info(File, KeyVals, AI#app_info{id = Val}, Status);
+ vsn ->
+ parse_app_info(File, KeyVals, AI#app_info{vsn = Val}, Status);
+ modules ->
+ parse_app_info(File, KeyVals, AI#app_info{modules = Val}, Status);
+ maxP ->
+ parse_app_info(File, KeyVals, AI#app_info{maxP = Val}, Status);
+ maxT ->
+ parse_app_info(File, KeyVals, AI#app_info{maxT = Val}, Status);
+ registered ->
+ parse_app_info(File, KeyVals, AI#app_info{registered = Val},
+ Status);
+ included_applications ->
+ parse_app_info(File, KeyVals, AI#app_info{incl_apps = Val}, Status);
+ applications ->
+ parse_app_info(File, KeyVals, AI#app_info{applications = Val},
+ Status);
+ env ->
+ parse_app_info(File, KeyVals, AI#app_info{env = Val}, Status);
+ mod ->
+ parse_app_info(File, KeyVals, AI#app_info{mod = Val}, Status);
+ start_phases ->
+ parse_app_info(File, KeyVals, AI#app_info{start_phases = Val},
+ Status);
+ _ ->
+ String = lists:concat(["Unexpected item ",
+ Key, "in app file ", File]),
+ parse_app_info(File, KeyVals, AI,
+ reltool_utils:add_warning(Status, String))
end;
parse_app_info(_, [], AI, Status) ->
{AI, Status}.
@@ -824,7 +920,7 @@ read_ebin_mods(Ebin, AppName) ->
Ext = code:objfile_extension(),
InitMod = fun(F) ->
File = filename:join([Ebin, F]),
- init_mod(AppName, File, File, Ext)
+ init_mod(AppName, File, File, Ext)
end,
Files2 = [F || F <- Files, filename:extension(F) =:= Ext],
pmap(InitMod, Files2);
@@ -839,7 +935,7 @@ pmap(Fun, List) ->
%% -record(pmap_res, {count, ref, res}).
%% -record(pmap_wait, {count, ref, pid}).
-%%
+%%
%% pmap(Fun, [H | T], N, Max, Count, WaitFor, Results) when N < Max ->
%% Ref = make_ref(),
%% Parent = self(),
@@ -943,16 +1039,16 @@ set_mod_flags(Mods, AppModNames) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-do_get_config(S, InclDefaults, InclDerivates) ->
+do_get_config(S, InclDef, InclDeriv) ->
S2 =
- case InclDerivates of
+ case InclDeriv of
false -> shrink_sys(S);
true -> S
end,
- {ok, reltool_target:gen_config(S2#state.sys, InclDefaults)}.
+ {ok, reltool_target:gen_config(S2#state.sys, InclDef)}.
-do_save_config(S, Filename, InclDefaults, InclDerivates) ->
- {ok, Config} = do_get_config(S, InclDefaults, InclDerivates),
+do_save_config(S, Filename, InclDef, InclDeriv) ->
+ {ok, Config} = do_get_config(S, InclDef, InclDeriv),
IoList = io_lib:format("%% config generated at ~w ~w\n~p.\n\n",
[date(), time(), Config]),
file:write_file(Filename, IoList).
@@ -963,13 +1059,15 @@ do_load_config(S, SysConfig) ->
OldSys = S#state.sys,
S2 = shrink_sys(S),
ShrinkedSys = S2#state.sys,
- {NewSys, Status} = read_config(ShrinkedSys#sys{apps = []}, SysConfig, {ok, []}),
+ {NewSys, Status} =
+ read_config(ShrinkedSys#sys{apps = []}, SysConfig, {ok, []}),
case Status of
{ok, _Warnings} ->
Force = false,
{MergedSys, Status2} = merge_config(OldSys, NewSys, Force, Status),
- {S3, Status3} = analyse(S2#state{sys = MergedSys, old_sys = OldSys}, Status2),
- S4 =
+ {S3, Status3} =
+ analyse(S2#state{sys = MergedSys, old_sys = OldSys}, Status2),
+ S4 =
case Status3 of
{ok, _Warnings2} ->
S3#state{status = Status3, old_status = S#state.status};
@@ -988,10 +1086,15 @@ read_config(OldSys, Filename, Status) when is_list(Filename) ->
read_config(OldSys, SysConfig, Status);
{ok, Content} ->
Text = lists:flatten(io_lib:format("~p", [Content])),
- {OldSys, reltool_utils:return_first_error(Status, "Illegal file content: " ++ Text)};
+ {OldSys,
+ reltool_utils:return_first_error(Status,
+ "Illegal file content: " ++
+ Text)};
{error, Reason} ->
Text = file:format_error(Reason),
- {OldSys, reltool_utils:return_first_error(Status, "File access: " ++ Text)}
+ {OldSys,
+ reltool_utils:return_first_error(Status, "File access: " ++
+ Text)}
end;
read_config(OldSys, {sys, KeyVals}, Status) ->
{NewSys, Status2} =
@@ -1006,7 +1109,7 @@ read_config(OldSys, {sys, KeyVals}, Status) ->
[] -> Rels = reltool_utils:default_rels();
Rels -> ok
end,
- NewSys2 = NewSys#sys{apps = lists:sort(Apps), rels = lists:sort(Rels)},
+ NewSys2 = NewSys#sys{apps = lists:sort(Apps), rels = lists:sort(Rels)},
case lists:keysearch(NewSys2#sys.boot_rel, #rel.name, NewSys2#sys.rels) of
{value, _} ->
{NewSys2, Status2};
@@ -1016,9 +1119,11 @@ read_config(OldSys, {sys, KeyVals}, Status) ->
end;
read_config(OldSys, BadConfig, Status) ->
Text = lists:flatten(io_lib:format("~p", [BadConfig])),
- {OldSys, reltool_utils:return_first_error(Status, "Illegal content: " ++ Text)}.
+ {OldSys,
+ reltool_utils:return_first_error(Status, "Illegal content: " ++ Text)}.
-decode(#sys{apps = Apps} = Sys, [{erts = Name, AppKeyVals} | SysKeyVals], Status)
+decode(#sys{apps = Apps} = Sys, [{erts = Name, AppKeyVals} | SysKeyVals],
+ Status)
when is_atom(Name), is_list(AppKeyVals) ->
App = default_app(Name),
{App2, Status2} = decode(App, AppKeyVals, Status),
@@ -1028,7 +1133,8 @@ decode(#sys{apps = Apps} = Sys, [{app, Name, AppKeyVals} | SysKeyVals], Status)
App = default_app(Name),
{App2, Status2} = decode(App, AppKeyVals, Status),
decode(Sys#sys{apps = [App2 | Apps]}, SysKeyVals, Status2);
-decode(#sys{apps = Apps, escripts = Escripts} = Sys, [{escript, File, AppKeyVals} | SysKeyVals], Status)
+decode(#sys{apps = Apps, escripts = Escripts} = Sys,
+ [{escript, File, AppKeyVals} | SysKeyVals], Status)
when is_list(File), is_list(AppKeyVals) ->
{Name, Label} = split_escript_name(File),
App = default_app(Name, File),
@@ -1038,14 +1144,17 @@ decode(#sys{apps = Apps, escripts = Escripts} = Sys, [{escript, File, AppKeyVals
active_dir = File,
sorted_dirs = [File]},
{App3, Status2} = decode(App2, AppKeyVals, Status),
- decode(Sys#sys{apps = [App3 | Apps], escripts = [File | Escripts]}, SysKeyVals, Status2);
-decode(#sys{rels = Rels} = Sys, [{rel, Name, Vsn, RelApps} | SysKeyVals], Status)
+ decode(Sys#sys{apps = [App3 | Apps], escripts = [File | Escripts]},
+ SysKeyVals,
+ Status2);
+decode(#sys{rels = Rels} = Sys, [{rel, Name, Vsn, RelApps} | SysKeyVals],
+ Status)
when is_list(Name), is_list(Vsn), is_list(RelApps) ->
Rel = #rel{name = Name, vsn = Vsn, rel_apps = []},
{Rel2, Status2} = decode(Rel, RelApps, Status),
decode(Sys#sys{rels = [Rel2 | Rels]}, SysKeyVals, Status2);
decode(#sys{} = Sys, [{Key, Val} | KeyVals], Status) ->
- {Sys3, Status3} =
+ {Sys3, Status3} =
case Key of
root_dir when is_list(Val) ->
{Sys#sys{root_dir = Val}, Status};
@@ -1053,10 +1162,10 @@ decode(#sys{} = Sys, [{Key, Val} | KeyVals], Status) ->
{Sys#sys{lib_dirs = Val}, Status};
mod_cond when Val =:= all; Val =:= app;
Val =:= ebin; Val =:= derived;
- Val =:= none ->
+ Val =:= none ->
{Sys#sys{mod_cond = Val}, Status};
incl_cond when Val =:= include; Val =:= exclude;
- Val =:= derived ->
+ Val =:= derived ->
{Sys#sys{incl_cond = Val}, Status};
boot_rel when is_list(Val) ->
{Sys#sys{boot_rel = Val}, Status};
@@ -1065,122 +1174,194 @@ decode(#sys{} = Sys, [{Key, Val} | KeyVals], Status) ->
profile when Val =:= development ->
Val = ?DEFAULT_PROFILE, % assert,
{Sys#sys{profile = Val,
- incl_sys_filters = reltool_utils:decode_regexps(incl_sys_filters,
- ?DEFAULT_INCL_SYS_FILTERS,
- Sys#sys.incl_sys_filters),
- excl_sys_filters = reltool_utils:decode_regexps(excl_sys_filters,
- ?DEFAULT_EXCL_SYS_FILTERS,
- Sys#sys.excl_sys_filters),
- incl_app_filters = reltool_utils:decode_regexps(incl_app_filters,
- ?DEFAULT_INCL_APP_FILTERS,
- Sys#sys.incl_app_filters),
- excl_app_filters = reltool_utils:decode_regexps(excl_app_filters,
- ?DEFAULT_EXCL_APP_FILTERS,
- Sys#sys.excl_app_filters)},
+ incl_sys_filters =
+ reltool_utils:decode_regexps(incl_sys_filters,
+ ?DEFAULT_INCL_SYS_FILTERS,
+ Sys#sys.incl_sys_filters),
+ excl_sys_filters =
+ reltool_utils:decode_regexps(excl_sys_filters,
+ ?DEFAULT_EXCL_SYS_FILTERS,
+ Sys#sys.excl_sys_filters),
+ incl_app_filters =
+ reltool_utils:decode_regexps(incl_app_filters,
+ ?DEFAULT_INCL_APP_FILTERS,
+ Sys#sys.incl_app_filters),
+ excl_app_filters =
+ reltool_utils:decode_regexps(excl_app_filters,
+ ?DEFAULT_EXCL_APP_FILTERS,
+ Sys#sys.excl_app_filters)},
Status};
profile when Val =:= embedded ->
{Sys#sys{profile = Val,
- incl_sys_filters = reltool_utils:decode_regexps(incl_sys_filters,
- ?EMBEDDED_INCL_SYS_FILTERS,
- Sys#sys.incl_sys_filters),
- excl_sys_filters = reltool_utils:decode_regexps(excl_sys_filters,
- ?EMBEDDED_EXCL_SYS_FILTERS,
- Sys#sys.excl_sys_filters),
- incl_app_filters = reltool_utils:decode_regexps(incl_app_filters,
- ?EMBEDDED_INCL_APP_FILTERS,
- Sys#sys.incl_app_filters),
- excl_app_filters = reltool_utils:decode_regexps(excl_app_filters,
- ?EMBEDDED_EXCL_APP_FILTERS,
- Sys#sys.excl_app_filters)},
+ incl_sys_filters =
+ reltool_utils:decode_regexps(incl_sys_filters,
+ ?EMBEDDED_INCL_SYS_FILTERS,
+ Sys#sys.incl_sys_filters),
+ excl_sys_filters =
+ reltool_utils:decode_regexps(excl_sys_filters,
+ ?EMBEDDED_EXCL_SYS_FILTERS,
+ Sys#sys.excl_sys_filters),
+ incl_app_filters =
+ reltool_utils:decode_regexps(incl_app_filters,
+ ?EMBEDDED_INCL_APP_FILTERS,
+ Sys#sys.incl_app_filters),
+ excl_app_filters =
+ reltool_utils:decode_regexps(excl_app_filters,
+ ?EMBEDDED_EXCL_APP_FILTERS,
+ Sys#sys.excl_app_filters)},
Status};
profile when Val =:= standalone ->
{Sys#sys{profile = Val,
- incl_sys_filters = reltool_utils:decode_regexps(incl_sys_filters,
- ?STANDALONE_INCL_SYS_FILTERS,
- Sys#sys.incl_sys_filters),
- excl_sys_filters = reltool_utils:decode_regexps(excl_sys_filters,
- ?STANDALONE_EXCL_SYS_FILTERS,
- Sys#sys.excl_sys_filters),
- incl_app_filters = reltool_utils:decode_regexps(incl_app_filters,
- ?STANDALONE_INCL_APP_FILTERS,
- Sys#sys.incl_app_filters),
- excl_app_filters = reltool_utils:decode_regexps(excl_app_filters,
- ?STANDALONE_EXCL_APP_FILTERS,
- Sys#sys.excl_app_filters)},
+ incl_sys_filters =
+ reltool_utils:decode_regexps(incl_sys_filters,
+ ?STANDALONE_INCL_SYS_FILTERS,
+ Sys#sys.incl_sys_filters),
+ excl_sys_filters =
+ reltool_utils:decode_regexps(excl_sys_filters,
+ ?STANDALONE_EXCL_SYS_FILTERS,
+ Sys#sys.excl_sys_filters),
+ incl_app_filters =
+ reltool_utils:decode_regexps(incl_app_filters,
+ ?STANDALONE_INCL_APP_FILTERS,
+ Sys#sys.incl_app_filters),
+ excl_app_filters =
+ reltool_utils:decode_regexps(excl_app_filters,
+ ?STANDALONE_EXCL_APP_FILTERS,
+ Sys#sys.excl_app_filters)},
Status};
incl_sys_filters ->
- {Sys#sys{incl_sys_filters = reltool_utils:decode_regexps(Key, Val, Sys#sys.incl_sys_filters)}, Status};
+ {Sys#sys{incl_sys_filters =
+ reltool_utils:decode_regexps(Key,
+ Val,
+ Sys#sys.incl_sys_filters)},
+ Status};
excl_sys_filters ->
- {Sys#sys{excl_sys_filters = reltool_utils:decode_regexps(Key, Val, Sys#sys.excl_sys_filters)}, Status};
+ {Sys#sys{excl_sys_filters =
+ reltool_utils:decode_regexps(Key,
+ Val,
+ Sys#sys.excl_sys_filters)},
+ Status};
incl_app_filters ->
- {Sys#sys{incl_app_filters = reltool_utils:decode_regexps(Key, Val, Sys#sys.incl_app_filters)}, Status};
+ {Sys#sys{incl_app_filters =
+ reltool_utils:decode_regexps(Key,
+ Val,
+ Sys#sys.incl_app_filters)},
+ Status};
excl_app_filters ->
- {Sys#sys{excl_app_filters = reltool_utils:decode_regexps(Key, Val, Sys#sys.excl_app_filters)}, Status};
+ {Sys#sys{excl_app_filters =
+ reltool_utils:decode_regexps(Key,
+ Val,
+ Sys#sys.excl_app_filters)},
+ Status};
incl_archive_filters ->
- {Sys#sys{incl_archive_filters = reltool_utils:decode_regexps(Key, Val, Sys#sys.incl_archive_filters)}, Status};
+ {Sys#sys{incl_archive_filters =
+ reltool_utils:decode_regexps(Key,
+ Val,
+ Sys#sys.incl_archive_filters)},
+ Status};
excl_archive_filters ->
- {Sys#sys{excl_archive_filters = reltool_utils:decode_regexps(Key, Val, Sys#sys.excl_archive_filters)}, Status};
+ {Sys#sys{excl_archive_filters =
+ reltool_utils:decode_regexps(Key,
+ Val,
+ Sys#sys.excl_archive_filters)},
+ Status};
archive_opts when is_list(Val) ->
{Sys#sys{archive_opts = Val}, Status};
relocatable when Val =:= true; Val =:= false ->
{Sys#sys{relocatable = Val}, Status};
- app_type when Val =:= permanent; Val =:= transient; Val =:= temporary;
- Val =:= load; Val =:= none ->
+ app_type when Val =:= permanent;
+ Val =:= transient;
+ Val =:= temporary;
+ Val =:= load; Val =:= none ->
{Sys#sys{app_type = Val}, Status};
- app_file when Val =:= keep; Val =:= strip, Val =:= all ->
+ app_file when Val =:= keep; Val =:= strip, Val =:= all ->
{Sys#sys{app_file = Val}, Status};
- debug_info when Val =:= keep; Val =:= strip ->
+ debug_info when Val =:= keep; Val =:= strip ->
{Sys#sys{debug_info = Val}, Status};
_ ->
Text = lists:flatten(io_lib:format("~p", [{Key, Val}])),
- {Sys, reltool_utils:return_first_error(Status, "Illegal option: " ++ Text)}
+ {Sys, reltool_utils:return_first_error(Status,
+ "Illegal option: " ++
+ Text)}
end,
decode(Sys3, KeyVals, Status3);
decode(#app{} = App, [{Key, Val} | KeyVals], Status) ->
- {App2, Status2} =
+ {App2, Status2} =
case Key of
- mod_cond when Val =:= all; Val =:= app; Val =:= ebin; Val =:= derived; Val =:= none ->
+ mod_cond when Val =:= all;
+ Val =:= app;
+ Val =:= ebin;
+ Val =:= derived;
+ Val =:= none ->
{App#app{mod_cond = Val}, Status};
- incl_cond when Val =:= include; Val =:= exclude; Val =:= derived ->
+ incl_cond when Val =:= include;
+ Val =:= exclude;
+ Val =:= derived ->
{App#app{incl_cond = Val}, Status};
- debug_info when Val =:= keep; Val =:= strip ->
+ debug_info when Val =:= keep;
+ Val =:= strip ->
{App#app{debug_info = Val}, Status};
- app_file when Val =:= keep; Val =:= strip, Val =:= all ->
+ app_file when Val =:= keep;
+ Val =:= strip,
+ Val =:= all ->
{App#app{app_file = Val}, Status};
- app_type when Val =:= permanent; Val =:= transient; Val =:= temporary;
- Val =:= load; Val =:= none ->
+ app_type when Val =:= permanent;
+ Val =:= transient;
+ Val =:= temporary;
+ Val =:= load;
+ Val =:= none ->
{App#app{app_type = Val}, Status};
incl_app_filters ->
- {App#app{incl_app_filters = reltool_utils:decode_regexps(Key, Val, App#app.incl_app_filters)}, Status};
+ {App#app{incl_app_filters =
+ reltool_utils:decode_regexps(Key,
+ Val,
+ App#app.incl_app_filters)},
+ Status};
excl_app_filters ->
- {App#app{excl_app_filters = reltool_utils:decode_regexps(Key, Val, App#app.excl_app_filters)}, Status};
+ {App#app{excl_app_filters =
+ reltool_utils:decode_regexps(Key,
+ Val,
+ App#app.excl_app_filters)},
+ Status};
incl_archive_filters ->
- {App#app{incl_archive_filters = reltool_utils:decode_regexps(Key, Val, App#app.incl_archive_filters)}, Status};
+ {App#app{incl_archive_filters =
+ reltool_utils:decode_regexps(Key,
+ Val,
+ App#app.incl_archive_filters)},
+ Status};
excl_archive_filters ->
- {App#app{excl_archive_filters = reltool_utils:decode_regexps(Key, Val, App#app.excl_archive_filters)}, Status};
+ {App#app{excl_archive_filters =
+ reltool_utils:decode_regexps(Key,
+ Val,
+ App#app.excl_archive_filters)},
+ Status};
archive_opts when is_list(Val) ->
{App#app{archive_opts = Val}, Status};
- vsn when is_list(Val) ->
+ vsn when is_list(Val) ->
{App#app{use_selected_vsn = true, vsn = Val}, Status};
_ ->
Text = lists:flatten(io_lib:format("~p", [{Key, Val}])),
- {App, reltool_utils:return_first_error(Status, "Illegal option: " ++ Text)}
+ {App, reltool_utils:return_first_error(Status,
+ "Illegal option: " ++ Text)}
end,
decode(App2, KeyVals, Status2);
-decode(#app{mods = Mods} = App, [{mod, Name, ModKeyVals} | AppKeyVals], Status) ->
+decode(#app{mods = Mods} = App, [{mod, Name, ModKeyVals} | AppKeyVals],
+ Status) ->
{Mod, Status2} = decode(#mod{name = Name}, ModKeyVals, Status),
decode(App#app{mods = [Mod | Mods]}, AppKeyVals, Status2);
decode(#mod{} = Mod, [{Key, Val} | KeyVals], Status) ->
- {Mod2, Status2} =
+ {Mod2, Status2} =
case Key of
- incl_cond when Val =:= include; Val =:= exclude; Val =:= derived ->
+ incl_cond when Val =:= include; Val =:= exclude; Val =:= derived ->
{Mod#mod{incl_cond = Val}, Status};
- debug_info when Val =:= keep; Val =:= strip ->
+ debug_info when Val =:= keep; Val =:= strip ->
{Mod#mod{debug_info = Val}, Status};
_ ->
Text = lists:flatten(io_lib:format("~p", [{Key, Val}])),
- {Mod, reltool_utils:return_first_error(Status, "Illegal option: " ++ Text)}
+ {Mod,
+ reltool_utils:return_first_error(Status,
+ "Illegal option: " ++ Text)}
end,
decode(Mod2, KeyVals, Status2);
decode(#rel{rel_apps = RelApps} = Rel, [RelApp | KeyVals], Status) ->
@@ -1191,7 +1372,9 @@ decode(#rel{rel_apps = RelApps} = Rel, [RelApp | KeyVals], Status) ->
{Name, Type} when is_atom(Name) ->
#rel_app{name = Name, app_type = Type, incl_apps = []};
{Name, InclApps} when is_atom(Name), is_list(InclApps) ->
- #rel_app{name = Name, app_type = undefined, incl_apps = InclApps};
+ #rel_app{name = Name,
+ app_type = undefined,
+ incl_apps = InclApps};
{Name, Type, InclApps} when is_atom(Name), is_list(InclApps) ->
#rel_app{name = Name, app_type = Type, incl_apps = InclApps};
_ ->
@@ -1204,7 +1387,9 @@ decode(#rel{rel_apps = RelApps} = Rel, [RelApp | KeyVals], Status) ->
decode(Rel#rel{rel_apps = RelApps ++ [RA]}, KeyVals, Status);
true ->
Text = lists:flatten(io_lib:format("~p", [RelApp])),
- Status2 = reltool_utils:return_first_error(Status, "Illegal option: " ++ Text),
+ Status2 =
+ reltool_utils:return_first_error(Status,
+ "Illegal option: " ++ Text),
decode(Rel, KeyVals, Status2)
end;
decode(Acc, [], Status) ->
@@ -1227,7 +1412,7 @@ is_type(Type) ->
split_escript_name(File) when is_list(File) ->
Label = filename:basename(File, ".escript"),
{list_to_atom("*escript* " ++ Label), Label}.
-
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
refresh(#state{sys = Sys} = S, Force, Status) ->
@@ -1245,7 +1430,8 @@ merge_config(OldSys, NewSys, Force, Status) ->
escripts_to_apps(Escripts, MergedApps, OldSys#sys.apps, Status2),
{RefreshedApps, Status4} =
refresh_apps(OldSys#sys.apps, AllApps, [], Force, Status3),
- {PatchedApps, Status5} = patch_erts_version(RootDir, RefreshedApps, Status4),
+ {PatchedApps, Status5} =
+ patch_erts_version(RootDir, RefreshedApps, Status4),
Escripts2 = [A#app.active_dir || A <- PatchedApps, A#app.is_escript],
NewSys2 = NewSys#sys{root_dir = RootDir,
lib_dirs = LibDirs,
@@ -1255,8 +1441,9 @@ merge_config(OldSys, NewSys, Force, Status) ->
verify_config(Sys, Status) ->
case lists:keymember(Sys#sys.boot_rel, #rel.name, Sys#sys.rels) of
- true ->
- lists:foreach(fun(Rel)-> check_rel(Rel, Sys, Status) end, Sys#sys.rels),
+ true ->
+ lists:foreach(fun(Rel)-> check_rel(Rel, Sys, Status) end,
+ Sys#sys.rels),
Status;
false ->
Text = lists:concat([Sys#sys.boot_rel, ": release is mandatory"]),
@@ -1264,15 +1451,19 @@ verify_config(Sys, Status) ->
throw({error, Status2})
end.
-check_rel(#rel{name = RelName, rel_apps = RelApps}, #sys{apps = Apps}, Status) ->
+check_rel(#rel{name = RelName, rel_apps = RelApps},
+ #sys{apps = Apps},
+ Status) ->
EnsureApp =
fun(AppName) ->
case lists:keymember(AppName, #rel_app.name, RelApps) of
true ->
ok;
false ->
- Text = lists:concat([RelName, ": ", AppName, " is not included."]),
- Status2 = reltool_utils:return_first_error(Status, Text),
+ Text = lists:concat([RelName, ": ", AppName,
+ " is not included."]),
+ Status2 =
+ reltool_utils:return_first_error(Status, Text),
throw({error, Status2})
end
end,
@@ -1286,9 +1477,11 @@ check_rel(#rel{name = RelName, rel_apps = RelApps}, #sys{apps = Apps}, Status) -
{value, App} when App#app.is_included ->
ok;
_ ->
- Text = lists:concat([RelName, ": uses application ",
- AppName, " that not is included."]),
- Status2 = reltool_utils:return_first_error(Status, Text),
+ Text =
+ lists:concat([RelName, ": uses application ",
+ AppName, " that not is included."]),
+ Status2 =
+ reltool_utils:return_first_error(Status, Text),
%% throw BUGBUG: add throw
({error, Status2})
end
@@ -1308,13 +1501,14 @@ patch_erts_version(RootDir, Apps, Status) ->
Apps2 = lists:keystore(AppName, #app.name, Apps, Erts2),
{Apps2, Status};
Vsn =:= "" ->
- {Apps, reltool_utils:add_warning(Status, "erts has no version")};
+ {Apps, reltool_utils:add_warning(Status,
+ "erts has no version")};
true ->
{Apps, Status}
end;
false ->
Text = "erts cannnot be found in the root directory " ++ RootDir,
- Status2 = reltool_utils:return_first_error(Status, Text),
+ Status2 = reltool_utils:return_first_error(Status, Text),
{Apps, Status2}
end.
@@ -1327,21 +1521,31 @@ libs_to_dirs(RootDir, LibDirs, Status) ->
[] ->
Fun = fun(Base) ->
AppDir = filename:join([RootLibDir, Base]),
- case filelib:is_dir(filename:join([AppDir, "ebin"]), erl_prim_loader) of
+ case filelib:is_dir(filename:join([AppDir,
+ "ebin"]),
+ erl_prim_loader) of
true ->
AppDir;
false ->
- filename:join([RootDir, Base, "preloaded"])
+ filename:join([RootDir,
+ Base,
+ "preloaded"])
end
end,
- ErtsFiles = [{erts, Fun(F)} || F <- RootFiles, lists:prefix("erts", F)],
+ ErtsFiles = [{erts, Fun(F)} || F <- RootFiles,
+ lists:prefix("erts", F)],
app_dirs2(AllLibDirs, [ErtsFiles], Status);
[Duplicate | _] ->
- {[], reltool_utils:return_first_error(Status, "Duplicate library: " ++ Duplicate)}
+ {[],
+ reltool_utils:return_first_error(Status,
+ "Duplicate library: " ++
+ Duplicate)}
end;
{error, Reason} ->
Text = file:format_error(Reason),
- {[], reltool_utils:return_first_error(Status, "Missing root library " ++ RootDir ++ ": " ++ Text)}
+ {[], reltool_utils:return_first_error(Status,
+ "Missing root library " ++
+ RootDir ++ ": " ++ Text)}
end.
app_dirs2([Lib | Libs], Acc, Status) ->
@@ -1352,8 +1556,9 @@ app_dirs2([Lib | Libs], Acc, Status) ->
AppDir = filename:join([Lib, Base]),
EbinDir = filename:join([AppDir, "ebin"]),
case filelib:is_dir(EbinDir, erl_prim_loader) of
- true ->
- {Name, _Vsn} = reltool_utils:split_app_name(Base),
+ true ->
+ {Name, _Vsn} =
+ reltool_utils:split_app_name(Base),
case Name of
erts -> false;
_ -> {true, {Name, AppDir}}
@@ -1366,7 +1571,9 @@ app_dirs2([Lib | Libs], Acc, Status) ->
app_dirs2(Libs, [Files2 | Acc], Status);
{error, Reason} ->
Text = file:format_error(Reason),
- {[], reltool_utils:return_first_error(Status, "Illegal library " ++ Lib ++ ": " ++ Text)}
+ {[], reltool_utils:return_first_error(Status,
+ "Illegal library " ++
+ Lib ++ ": " ++ Text)}
end;
app_dirs2([], Acc, Status) ->
{lists:sort(lists:append(Acc)), Status}.
@@ -1380,17 +1587,29 @@ escripts_to_apps([Escript | Escripts], Apps, OldApps, Status) ->
[AppLabel, "ebin", File] ->
case filename:extension(File) of
".app" ->
- {AppName, DefaultVsn} = reltool_utils:split_app_name(AppLabel),
- AppFileName = filename:join([Escript, FullName]),
+ {AppName, DefaultVsn} =
+ reltool_utils:split_app_name(AppLabel),
+ AppFileName =
+ filename:join([Escript, FullName]),
{Info, StatusAcc2} =
- read_app_info(GetBin(), AppFileName, AppName, DefaultVsn, Status),
+ read_app_info(GetBin(),
+ AppFileName,
+ AppName,
+ DefaultVsn,
+ Status),
Dir = filename:join([Escript, AppName]),
- {[{AppName, app, Dir, Info} | FileAcc], StatusAcc2};
+ {[{AppName, app, Dir, Info} | FileAcc],
+ StatusAcc2};
E when E =:= Ext ->
- {AppName, _} = reltool_utils:split_app_name(AppLabel),
- Mod = init_mod(AppName, File, {File, GetBin()}, Ext),
+ {AppName, _} =
+ reltool_utils:split_app_name(AppLabel),
+ Mod = init_mod(AppName,
+ File,
+ {File, GetBin()},
+ Ext),
Dir = filename:join([Escript, AppName]),
- {[{AppName, mod, Dir, Mod} | FileAcc], StatusAcc};
+ {[{AppName, mod, Dir, Mod} | FileAcc],
+ StatusAcc};
_ ->
{FileAcc, StatusAcc}
end;
@@ -1398,13 +1617,21 @@ escripts_to_apps([Escript | Escripts], Apps, OldApps, Status) ->
Bin = GetBin(),
{ok, {ModName, _}} = beam_lib:version(Bin),
ModStr = atom_to_list(ModName) ++ Ext,
- Mod = init_mod(EscriptAppName, ModStr, {ModStr, GetBin()}, Ext),
- {[{EscriptAppName, mod, Escript, Mod} | FileAcc], StatusAcc};
+ Mod = init_mod(EscriptAppName,
+ ModStr,
+ {ModStr, GetBin()},
+ Ext),
+ {[{EscriptAppName, mod, Escript, Mod} | FileAcc],
+ StatusAcc};
[File] ->
case filename:extension(File) of
E when E =:= Ext ->
- Mod = init_mod(EscriptAppName, File, {File, GetBin()}, Ext),
- {[{EscriptAppName, mod, File, Mod} | FileAcc], StatusAcc};
+ Mod = init_mod(EscriptAppName,
+ File,
+ {File, GetBin()},
+ Ext),
+ {[{EscriptAppName, mod, File, Mod} | FileAcc],
+ StatusAcc};
_ ->
{FileAcc, StatusAcc}
end;
@@ -1412,43 +1639,82 @@ escripts_to_apps([Escript | Escripts], Apps, OldApps, Status) ->
{FileAcc, StatusAcc}
end
end,
- try
- case escript:foldl(Fun, {[], Status}, Escript) of
- {ok, {Files, Status2}} ->
- {Apps2, Status3} = files_to_apps(Escript, lists:sort(Files), Apps, Apps, OldApps, Status2),
- escripts_to_apps(Escripts, Apps2, OldApps, Status3);
- {error, Reason} ->
- Text = lists:flatten(io_lib:format("~p", [Reason])),
- {[], reltool_utils:return_first_error(Status, "Illegal escript " ++ Escript ++ ": " ++ Text)}
- end
- catch
- throw:Reason2 when is_list(Reason2) ->
- {[], reltool_utils:return_first_error(Status, "Illegal escript " ++ Escript ++ ": " ++ Reason2)}
+ case reltool_utils:escript_foldl(Fun, {[], Status}, Escript) of
+ {ok, {Files, Status2}} ->
+ {Apps2, Status3} =
+ files_to_apps(Escript,
+ lists:sort(Files),
+ Apps,
+ Apps,
+ OldApps,
+ Status2),
+ escripts_to_apps(Escripts, Apps2, OldApps, Status3);
+ {error, Reason} ->
+ Text = lists:flatten(io_lib:format("~p", [Reason])),
+ {[], reltool_utils:return_first_error(Status,
+ "Illegal escript " ++
+ Escript ++ ": " ++ Text)}
end;
escripts_to_apps([], Apps, _OldApps, Status) ->
{Apps, Status}.
%% Assume that all files for an app are in consecutive order
%% Assume the app info is before the mods
-files_to_apps(Escript, [{AppName, Type, Dir, ModOrInfo} | Files] = AllFiles, Acc, Apps, OldApps, Status) ->
+files_to_apps(Escript,
+ [{AppName, Type, Dir, ModOrInfo} | Files] = AllFiles,
+ Acc,
+ Apps,
+ OldApps,
+ Status) ->
case Type of
mod ->
case Acc of
[] ->
Info = missing_app_info(""),
- {NewApp, Status2} = merge_escript_app(AppName, Dir, Info, [ModOrInfo], Apps, OldApps, Status),
- files_to_apps(Escript, AllFiles, [NewApp | Acc], Apps, OldApps, Status2);
+ {NewApp, Status2} =
+ merge_escript_app(AppName,
+ Dir,
+ Info,
+ [ModOrInfo],
+ Apps,
+ OldApps,
+ Status),
+ files_to_apps(Escript,
+ AllFiles,
+ [NewApp | Acc],
+ Apps,
+ OldApps, Status2);
[App | Acc2] when App#app.name =:= ModOrInfo#mod.app_name ->
App2 = App#app{mods = [ModOrInfo | App#app.mods]},
- files_to_apps(Escript, Files, [App2 | Acc2], Apps, OldApps, Status);
+ files_to_apps(Escript,
+ Files,
+ [App2 | Acc2],
+ Apps,
+ OldApps,
+ Status);
[App | Acc2] ->
- PrevApp = App#app{mods = lists:keysort(#mod.name, App#app.mods)},
+ PrevApp = App#app{mods = lists:keysort(#mod.name,
+ App#app.mods)},
Info = missing_app_info(""),
- {NewApp, Status2} = merge_escript_app(AppName, Dir, Info, [ModOrInfo], Apps, OldApps, Status),
- files_to_apps(Escript, Files, [NewApp, PrevApp | Acc2], Apps, OldApps, Status2)
+ {NewApp, Status2} =
+ merge_escript_app(AppName,
+ Dir,
+ Info,
+ [ModOrInfo],
+ Apps,
+ OldApps,
+ Status),
+ files_to_apps(Escript,
+ Files,
+ [NewApp, PrevApp | Acc2],
+ Apps,
+ OldApps,
+ Status2)
end;
app ->
- {App, Status2} = merge_escript_app(AppName, Dir, ModOrInfo, [], Apps, OldApps, Status),
+ {App, Status2} =
+ merge_escript_app(AppName, Dir, ModOrInfo, [], Apps, OldApps,
+ Status),
files_to_apps(Escript, Files, [App | Acc], Apps, OldApps, Status2)
end;
files_to_apps(_Escript, [], Acc, _Apps, _OldApps, Status) ->
@@ -1470,13 +1736,14 @@ merge_escript_app(AppName, Dir, Info, Mods, Apps, OldApps, Status) ->
case lists:keysearch(AppName, #app.name, Apps) of
{value, _} ->
Error = lists:concat([AppName, ": Application name clash. ",
- "Escript ", Dir," contains application ", AppName, "."]),
+ "Escript ", Dir," contains application ",
+ AppName, "."]),
{App2, reltool_utils:return_first_error(Status, Error)};
false ->
{App2, Status}
end.
-merge_app_dirs([{Name, Dir} | Rest], [App | Apps], OldApps)
+merge_app_dirs([{Name, Dir} | Rest], [App | Apps], OldApps)
when App#app.name =:= Name ->
%% Add new dir to app
App2 = App#app{sorted_dirs = [Dir | App#app.sorted_dirs]},
@@ -1491,10 +1758,11 @@ merge_app_dirs([{Name, Dir} | Rest], Apps, OldApps) ->
{value, OldApp} when OldApp#app.active_dir =:= Dir ->
[OldApp | Apps2];
{value, OldApp} ->
- App =
+ App =
case filter_app(OldApp) of
{true, NewApp} ->
- NewApp#app{active_dir = Dir, sorted_dirs = [Dir]};
+ NewApp#app{active_dir = Dir,
+ sorted_dirs = [Dir]};
false ->
default_app(Name, Dir)
end,
@@ -1547,10 +1815,11 @@ default_app(Name) ->
is_pre_included = undefined,
is_included = undefined}.
-%% Assume that the application are sorted
-refresh_apps([Old | OldApps], [New | NewApps], Acc, Force, Status) when New#app.name =:= Old#app.name ->
+%% Assume that the application are sorted
+refresh_apps([Old | OldApps], [New | NewApps], Acc, Force, Status)
+ when New#app.name =:= Old#app.name ->
{Info, ActiveDir, Status2} = ensure_app_info(New, Status),
- OptLabel =
+ OptLabel =
case Info#app_info.vsn =:= New#app.vsn of
true -> New#app.label;
false -> undefined % Cause refresh
@@ -1559,23 +1828,28 @@ refresh_apps([Old | OldApps], [New | NewApps], Acc, Force, Status) when New#app.
refresh_app(New#app{label = OptLabel,
active_dir = ActiveDir,
vsn = Info#app_info.vsn,
- info = Info},
+ info = Info},
Force,
Status2),
refresh_apps(OldApps, NewApps, [Refreshed | Acc], Force, Status3);
-refresh_apps([Old | OldApps], [New | NewApps], Acc, Force, Status) when New#app.name < Old#app.name ->
+refresh_apps([Old | OldApps], [New | NewApps], Acc, Force, Status)
+ when New#app.name < Old#app.name ->
%% No old app version exists. Use new as is.
%% BUGBUG: Issue warning if the active_dir is not defined
{New2, Status2} = refresh_app(New, Force, Status),
refresh_apps([Old | OldApps], NewApps, [New2 | Acc], Force, Status2);
-refresh_apps([Old | OldApps], [New | NewApps], Acc, Force, Status) when New#app.name > Old#app.name ->
+refresh_apps([Old | OldApps], [New | NewApps], Acc, Force, Status)
+ when New#app.name > Old#app.name ->
%% No new version. Remove the old.
Status2 =
case Old#app.name =:= ?MISSING_APP of
true ->
Status;
false ->
- Warning = lists:concat([Old#app.name, ": The source dirs does not contain the application anymore."]),
+ Warning =
+ lists:concat([Old#app.name,
+ ": The source dirs does not ",
+ "contain the application anymore."]),
reltool_utils:add_warning(Status, Warning)
end,
refresh_apps(OldApps, [New | NewApps], Acc, Force, Status2);
@@ -1590,21 +1864,28 @@ refresh_apps([Old | OldApps], [], Acc, Force, Status) ->
true ->
Status;
false ->
- Warning = lists:concat([Old#app.name, ": The source dirs ",
- "does not contain the application anymore."]),
+ Warning =
+ lists:concat([Old#app.name,
+ ": The source dirs does not "
+ "contain the application anymore."]),
reltool_utils:add_warning(Status, Warning)
end,
refresh_apps(OldApps, [], Acc, Force, Status2);
refresh_apps([], [], Acc, _Force, Status) ->
{lists:reverse(Acc), Status}.
-ensure_app_info(#app{is_escript = true, active_dir = Dir, info = Info}, Status) ->
+ensure_app_info(#app{is_escript = true, active_dir = Dir, info = Info},
+ Status) ->
{Info, Dir, Status};
ensure_app_info(#app{name = Name, sorted_dirs = []}, Status) ->
Error = lists:concat([Name, ": Missing application directory."]),
Status2 = reltool_utils:return_first_error(Status, Error),
{missing_app_info(""), undefined, Status2};
-ensure_app_info(#app{name = Name, vsn = Vsn, sorted_dirs = Dirs, info = undefined}, Status) ->
+ensure_app_info(#app{name = Name,
+ vsn = Vsn,
+ sorted_dirs = Dirs,
+ info = undefined},
+ Status) ->
ReadInfo =
fun(Dir, StatusAcc) ->
Base = get_base(Name, Dir),
@@ -1621,8 +1902,10 @@ ensure_app_info(#app{name = Name, vsn = Vsn, sorted_dirs = Dirs, info = undefine
%% No redundant info
Status2;
[BadVsn | _] ->
- Error2 = lists:concat([Name, ": Application version clash. ",
- "Multiple directories contains version \"", BadVsn, "\"."]),
+ Error2 =
+ lists:concat([Name, ": Application version clash. ",
+ "Multiple directories contains version \"",
+ BadVsn, "\"."]),
reltool_utils:return_first_error(Status2, Error2)
end,
FirstInfo = hd(AllInfo),
@@ -1637,7 +1920,11 @@ ensure_app_info(#app{name = Name, vsn = Vsn, sorted_dirs = Dirs, info = undefine
{Info, VsnDir} ->
{Info, VsnDir, Status3};
false ->
- Error3 = lists:concat([Name, ": No application directory contains selected version \"", Vsn, "\"."]),
+ Error3 =
+ lists:concat([Name,
+ ": No application directory contains ",
+ "selected version \"",
+ Vsn, "\"."]),
Status4 = reltool_utils:return_first_error(Status3, Error3),
{FirstInfo, FirstDir, Status4}
end
diff --git a/lib/reltool/src/reltool_sys_win.erl b/lib/reltool/src/reltool_sys_win.erl
index ea80ab7e85..2e226d9147 100644
--- a/lib/reltool/src/reltool_sys_win.erl
+++ b/lib/reltool/src/reltool_sys_win.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
-module(reltool_sys_win).
@@ -34,7 +34,7 @@
-include_lib("wx/include/wx.hrl").
-include("reltool.hrl").
--record(state,
+-record(state,
{parent_pid,
server_pid,
app_wins,
@@ -61,7 +61,7 @@
-define(WIN_HEIGHT, 600).
-define(CLOSE_ITEM, ?wxID_EXIT). %% Use OS specific version if available
--define(ABOUT_ITEM, ?wxID_ABOUT). %% Use OS specific
+-define(ABOUT_ITEM, ?wxID_ABOUT). %% Use OS specific
-define(CONTENTS_ITEM, 300).
-define(APP_GRAPH_ITEM, 301).
-define(MOD_GRAPH_ITEM, 302).
@@ -100,7 +100,11 @@
%% Client
start_link(Opts) ->
- proc_lib:start_link(?MODULE, init, [[{parent, self()} | Opts]], infinity, []).
+ proc_lib:start_link(?MODULE,
+ init,
+ [[{parent, self()} | Opts]],
+ infinity,
+ []).
get_server(Pid) ->
reltool_utils:call(Pid, get_server).
@@ -146,9 +150,13 @@ do_init([{parent, Parent} | Options]) ->
S3 = S2#state{sys = Sys2},
S5 = wx:batch(fun() ->
Title = atom_to_list(?APPLICATION),
- wxFrame:setTitle(S3#state.frame, Title),
- %% wxFrame:setMinSize(Frame, {?WIN_WIDTH, ?WIN_HEIGHT}),
- wxStatusBar:setStatusText(S3#state.status_bar, "Done."),
+ wxFrame:setTitle(S3#state.frame,
+ Title),
+ %% wxFrame:setMinSize(Frame,
+ %% {?WIN_WIDTH, ?WIN_HEIGHT}),
+ wxStatusBar:setStatusText(
+ S3#state.status_bar,
+ "Done."),
S4 = redraw_apps(S3),
redraw_libs(S4)
end),
@@ -182,7 +190,12 @@ loop(S) ->
receive
{system, From, Msg} ->
Common = S#state.common,
- sys:handle_system_msg(Msg, From, S#state.parent_pid, ?MODULE, Common#common.sys_debug, S);
+ sys:handle_system_msg(Msg,
+ From,
+ S#state.parent_pid,
+ ?MODULE,
+ Common#common.sys_debug,
+ S);
#wx{obj = ObjRef,
event = #wxClose{type = close_window}} = Msg ->
if
@@ -193,17 +206,22 @@ loop(S) ->
FWs = S#state.fgraph_wins,
case lists:keysearch(ObjRef, #fgraph_win.frame, FWs) of
{value, FW} ->
- reltool_fgraph_win:stop(FW#fgraph_win.pid, shutdown),
+ reltool_fgraph_win:stop(FW#fgraph_win.pid,
+ shutdown),
wxFrame:destroy(ObjRef),
- FWs2 = lists:keydelete(ObjRef, #fgraph_win.frame, FWs),
+ FWs2 =
+ lists:keydelete(ObjRef, #fgraph_win.frame, FWs),
?MODULE:loop(S#state{fgraph_wins = FWs2});
false ->
- error_logger:format("~p~p got unexpected message:\n\t~p\n",
- [?MODULE, self(), Msg]),
+ error_logger:format("~p~p got unexpected "
+ "message:\n\t~p\n",
+ [?MODULE, self(), Msg]),
?MODULE:loop(S)
end
end;
- #wx{id = ?CLOSE_ITEM, event = #wxCommand{type = command_menu_selected}, userData = main_window} ->
+ #wx{id = ?CLOSE_ITEM,
+ event = #wxCommand{type = command_menu_selected},
+ userData = main_window} ->
wxFrame:destroy(S#state.frame),
exit(shutdown);
#wx{event = #wxSize{}} = Wx ->
@@ -222,14 +240,18 @@ loop(S) ->
?MODULE:loop(S2);
{call, ReplyTo, Ref, {open_app, AppName}} ->
S2 = do_open_app(S, AppName),
- {value, #app_win{pid = AppPid}} = lists:keysearch(AppName, #app_win.name, S2#state.app_wins),
+ {value, #app_win{pid = AppPid}} =
+ lists:keysearch(AppName, #app_win.name, S2#state.app_wins),
reltool_utils:reply(ReplyTo, Ref, {ok, AppPid}),
?MODULE:loop(S2);
{'EXIT', Pid, Reason} when Pid =:= S#state.parent_pid ->
- [reltool_fgraph_win:stop(FW#fgraph_win.pid, Reason) || FW <- S#state.fgraph_wins],
+ [reltool_fgraph_win:stop(FW#fgraph_win.pid, Reason) ||
+ FW <- S#state.fgraph_wins],
exit(Reason);
{'EXIT', _Pid, _Reason} = Exit ->
- {FWs, AWs} = handle_child_exit(Exit, S#state.fgraph_wins, S#state.app_wins),
+ {FWs, AWs} = handle_child_exit(Exit,
+ S#state.fgraph_wins,
+ S#state.app_wins),
?MODULE:loop(S#state{fgraph_wins = FWs, app_wins = AWs});
Msg ->
error_logger:format("~p~p got unexpected message:\n\t~p\n",
@@ -261,7 +283,8 @@ msg_warning(Exit, Type) ->
create_window(S) ->
Title = lists:concat([?APPLICATION, " - starting up"]),
- Frame = wxFrame:new(wx:null(), ?wxID_ANY, Title, [{size, {?WIN_WIDTH, ?WIN_HEIGHT}}]),
+ Frame = wxFrame:new(wx:null(), ?wxID_ANY, Title,
+ [{size, {?WIN_WIDTH, ?WIN_HEIGHT}}]),
%%wxFrame:setSize(Frame, {?WIN_WIDTH, ?WIN_HEIGHT}),
%% wxFrame:setMinSize(Frame, {?WIN_WIDTH, ?WIN_HEIGHT}),
Bar = wxFrame:createStatusBar(Frame,[]),
@@ -306,21 +329,29 @@ create_menubar(Frame) ->
File = wxMenu:new([]),
Help = wxMenu:new([]),
wxMenuBar:append(MenuBar, File, "File" ),
- wxMenu:append(File, ?APP_GRAPH_ITEM, "Display application dependency graph" ),
- wxMenu:append(File, ?MOD_GRAPH_ITEM, "Display module dependency graph" ),
+ wxMenu:append(File, ?APP_GRAPH_ITEM,
+ "Display application dependency graph" ),
+ wxMenu:append(File, ?MOD_GRAPH_ITEM,
+ "Display module dependency graph" ),
wxMenu:appendSeparator(File),
wxMenu:append(File, ?RESET_CONFIG_ITEM, "Reset configuration to default" ),
wxMenu:append(File, ?UNDO_CONFIG_ITEM, "Undo configuration (toggle)" ),
wxMenu:append(File, ?LOAD_CONFIG_ITEM, "Load configuration" ),
Save = wxMenu:new(),
- wxMenu:append(Save, ?SAVE_CONFIG_NODEF_NODER_ITEM, "Save explicit configuration (neither defaults nor derivates)"),
- wxMenu:append(Save, ?SAVE_CONFIG_DEF_NODER_ITEM , "Save configuration defaults (defaults only)"),
- wxMenu:append(Save, ?SAVE_CONFIG_NODEF_DER_ITEM, "Save configuration derivates (derivates only))"),
- wxMenu:append(Save, ?SAVE_CONFIG_DEF_DER_ITEM, "Save extended configuration (both defaults and derivates)"),
+ wxMenu:append(Save, ?SAVE_CONFIG_NODEF_NODER_ITEM,
+ "Save explicit configuration "
+ "(neither defaults nor derivates)"),
+ wxMenu:append(Save, ?SAVE_CONFIG_DEF_NODER_ITEM,
+ "Save configuration defaults (defaults only)"),
+ wxMenu:append(Save, ?SAVE_CONFIG_NODEF_DER_ITEM,
+ "Save configuration derivates (derivates only))"),
+ wxMenu:append(Save, ?SAVE_CONFIG_DEF_DER_ITEM,
+ "Save extended configuration (both defaults and derivates)"),
wxMenu:append(File, ?wxID_ANY, "Save configuration", Save),
wxMenu:appendSeparator(File),
- wxMenu:append(File, ?GEN_REL_FILES_ITEM, "Generate rel, script and boot files" ),
+ wxMenu:append(File, ?GEN_REL_FILES_ITEM,
+ "Generate rel, script and boot files" ),
wxMenu:append(File, ?GEN_TARGET_ITEM, "Generate target system" ),
wxMenu:appendSeparator(File),
wxMenu:append(File, ?CLOSE_ITEM, "Close" ),
@@ -375,12 +406,13 @@ create_app_list_ctrl(Panel, OuterSz, Title, Tick, Cross) ->
%% ?wxLC_SINGLE_SEL bor
?wxVSCROLL},
{size, {Width, Height}}]),
- ToolTip = "Select application(s) or open separate application window with a double click.",
+ ToolTip = "Select application(s) or open separate "
+ "application window with a double click.",
wxListCtrl:setToolTip(ListCtrl, ToolTip),
%% Prep images
reltool_utils:assign_image_list(ListCtrl),
-
+
%% Prep column label
ListItem = wxListItem:new(),
wxListItem:setAlign(ListItem, ?wxLIST_FORMAT_LEFT),
@@ -395,7 +427,7 @@ create_app_list_ctrl(Panel, OuterSz, Title, Tick, Cross) ->
InnerSz = wxBoxSizer:new(?wxVERTICAL),
- wxSizer:add(InnerSz,
+ wxSizer:add(InnerSz,
ListCtrl,
[{border, 2},
{flag, ?wxALL bor ?wxEXPAND},
@@ -408,9 +440,10 @@ create_app_list_ctrl(Panel, OuterSz, Title, Tick, Cross) ->
[{flag, ?wxEXPAND}, {proportion, 1}]),
%% Subscribe on events
- wxEvtHandler:connect(ListCtrl, size, [{skip, true}, {userData, app_list_ctrl}]),
+ wxEvtHandler:connect(ListCtrl, size,
+ [{skip, true}, {userData, app_list_ctrl}]),
wxEvtHandler:connect(ListCtrl, command_list_item_activated),
- wxWindow:connect(ListCtrl, enter_window),
+ wxWindow:connect(ListCtrl, enter_window),
ListCtrl.
@@ -423,7 +456,7 @@ create_button(Panel, Sizer, ListCtrl, Title, BitMapName, Action) ->
wxBitmapButton:setToolTip(Button, ToolTip),
Options = [{userData, {app_button, Action, ListCtrl}}],
wxEvtHandler:connect(Button, command_button_clicked, Options),
- wxSizer:add(Sizer,
+ wxSizer:add(Sizer,
Button,
[{border, 2},
{flag, ?wxALL},
@@ -439,7 +472,7 @@ action_to_tool_tip(Label, Action) ->
"Remove selected application(s)from whitelist.";
blacklist_add when Label =:= ?blacklist ->
"Remove selected application(s) from blacklist.";
- blacklist_add ->
+ blacklist_add ->
"Add selected application(s) to blacklist.";
blacklist_del ->
"Remove selected application(s) from blacklist."
@@ -448,8 +481,9 @@ action_to_tool_tip(Label, Action) ->
create_lib_page(#state{book = Book} = S) ->
Panel = wxPanel:new(Book, []),
Sizer = wxBoxSizer:new(?wxHORIZONTAL),
-
- Tree = wxTreeCtrl:new(Panel, [{style , ?wxTR_HAS_BUTTONS bor ?wxTR_HIDE_ROOT}]),
+
+ Tree = wxTreeCtrl:new(Panel,
+ [{style , ?wxTR_HAS_BUTTONS bor ?wxTR_HIDE_ROOT}]),
ToolTip = "Edit application sources.",
wxBitmapButton:setToolTip(Tree, ToolTip),
@@ -478,7 +512,9 @@ redraw_libs(#state{lib_tree = Tree, sys = Sys} = S) ->
[append_lib(Tree, LibItem, Dir) || Dir <- Sys#sys.lib_dirs],
EscriptItem = append_item(Tree, Top, "Escript files", undefined),
- EscriptData = #escript_data{file = undefined, tree = Tree, item = EscriptItem},
+ EscriptData = #escript_data{file = undefined,
+ tree = Tree,
+ item = EscriptItem},
wxTreeCtrl:setItemData(Tree,EscriptItem, EscriptData),
[append_escript(Tree, EscriptItem, File) || File <- Sys#sys.escripts],
wxTreeCtrl:expand(Tree, LibItem),
@@ -529,9 +565,9 @@ create_config_page(#state{sys = Sys, book = Book} = S) ->
Panel = wxPanel:new(Book, []),
Sizer = wxBoxSizer:new(?wxHORIZONTAL),
AppConds = reltool_utils:incl_conds(),
- AppBox = wxRadioBox:new(Panel,
+ AppBox = wxRadioBox:new(Panel,
?wxID_ANY,
- "Application inclusion policy",
+ "Application inclusion policy",
?wxDefaultPosition,
?wxDefaultSize,
AppConds,
@@ -543,9 +579,9 @@ create_config_page(#state{sys = Sys, book = Book} = S) ->
wxEvtHandler:connect(AppBox, command_radiobox_selected,
[{userData, config_incl_cond}]),
ModConds = reltool_utils:mod_conds(),
- ModBox = wxRadioBox:new(Panel,
+ ModBox = wxRadioBox:new(Panel,
?wxID_ANY,
- "Module inclusion policy",
+ "Module inclusion policy",
?wxDefaultPosition,
?wxDefaultSize,
ModConds,
@@ -582,19 +618,19 @@ create_main_release_page(#state{book = Book} = S) ->
wxButton:setToolTip(Create, "Create a new release."),
wxButton:connect(Create, command_button_clicked, [{userData, create_rel}]),
wxSizer:add(ButtonSizer, Create),
-
+
Delete = wxButton:new(Panel, ?wxID_ANY, [{label, "Delete"}]),
wxButton:setToolTip(Delete, "Delete a release."),
wxButton:connect(Delete, command_button_clicked, [{userData, delete_rel}]),
wxSizer:add(ButtonSizer, Delete),
-
+
View = wxButton:new(Panel, ?wxID_ANY, [{label, "View script"}]),
wxButton:setToolTip(View, "View generated script file."),
wxButton:connect(View, command_button_clicked, [{userData, view_script}]),
wxSizer:add(ButtonSizer, View),
[add_release_page(RelBook, Rel) || Rel <- (S#state.sys)#sys.rels],
-
+
wxSizer:add(Sizer, RelBook, [{flag, ?wxEXPAND}, {proportion, 1}]),
wxSizer:add(Sizer, ButtonSizer, [{flag, ?wxEXPAND}]),
wxPanel:setSizer(Panel, Sizer),
@@ -604,16 +640,18 @@ create_main_release_page(#state{book = Book} = S) ->
add_release_page(Book, #rel{name = RelName, rel_apps = RelApps}) ->
Panel = wxPanel:new(Book, []),
Sizer = wxBoxSizer:new(?wxHORIZONTAL),
- RelBox = wxRadioBox:new(Panel,
+ RelBox = wxRadioBox:new(Panel,
?wxID_ANY,
- "Applications included in the release " ++ RelName,
+ "Applications included in the release " ++ RelName,
?wxDefaultPosition,
?wxDefaultSize,
[atom_to_list(RA#rel_app.name) || RA <- RelApps],
[]),
%% wxRadioBox:setSelection(RelBox, 2), % mandatory
- wxEvtHandler:connect(RelBox, command_radiobox_selected, [{userData, {config_rel_cond, RelName}}]),
- RelToolTip = "Choose which applications that shall be included in the release resource file.",
+ wxEvtHandler:connect(RelBox, command_radiobox_selected,
+ [{userData, {config_rel_cond, RelName}}]),
+ RelToolTip = "Choose which applications that shall "
+ "be included in the release resource file.",
wxBitmapButton:setToolTip(RelBox, RelToolTip),
wxSizer:add(Sizer,
@@ -629,11 +667,14 @@ do_open_app(S, AppBase) when is_list(AppBase) ->
do_open_app(S, AppName);
do_open_app(S, '') ->
S;
-do_open_app(#state{server_pid = ServerPid, common = C, app_wins = AppWins} = S, AppName) when is_atom(AppName) ->
+do_open_app(#state{server_pid = ServerPid, common = C, app_wins = AppWins} = S,
+ AppName)
+ when is_atom(AppName) ->
case lists:keysearch(AppName, #app_win.name, AppWins) of
false ->
WxEnv = wx:get_env(),
- {ok, Pid} = reltool_app_win:start_link(WxEnv, ServerPid, C, AppName),
+ {ok, Pid} =
+ reltool_app_win:start_link(WxEnv, ServerPid, C, AppName),
AW = #app_win{name = AppName, pid = Pid},
S#state{app_wins = [AW | AppWins]};
{value, AW} ->
@@ -651,7 +692,10 @@ root_popup(S, Root, Tree, Item) ->
wxEvtHandler:connect(PopupMenu, menu_close),
wxWindow:popupMenu(S#state.frame, PopupMenu),
- Popup = #root_popup{dir = Root, choices = Choices, tree = Tree, item = Item},
+ Popup = #root_popup{dir = Root,
+ choices = Choices,
+ tree = Tree,
+ item = Item},
S#state{popup_menu = Popup}.
lib_popup(S, Lib, Tree, Item) ->
@@ -693,7 +737,10 @@ escript_popup(S, File, Tree, Item) ->
wxEvtHandler:connect(PopupMenu, menu_close),
wxWindow:popupMenu(S#state.frame, PopupMenu),
- Popup = #escript_popup{file = File, choices = Choices, tree = Tree, item = Item},
+ Popup = #escript_popup{file = File,
+ choices = Choices,
+ tree = Tree,
+ item = Item},
S#state{popup_menu = Popup}.
@@ -705,29 +752,40 @@ handle_event(S, #wx{id = Id, obj= ObjRef, userData = UserData, event = Event} =
#wxSize{type = size, size = {W, _H}} when UserData =:= app_list_ctrl ->
wxListCtrl:setColumnWidth(ObjRef, ?APPS_APP_COL, W),
S;
- #wxCommand{type = command_menu_selected} when Id =:= ?APP_GRAPH_ITEM ->
+ #wxCommand{type = command_menu_selected}
+ when Id =:= ?APP_GRAPH_ITEM ->
update_app_graph(S);
- #wxCommand{type = command_menu_selected} when Id =:= ?MOD_GRAPH_ITEM ->
+ #wxCommand{type = command_menu_selected}
+ when Id =:= ?MOD_GRAPH_ITEM ->
update_mod_graph(S);
- #wxCommand{type = command_menu_selected} when Id =:= ?RESET_CONFIG_ITEM ->
+ #wxCommand{type = command_menu_selected}
+ when Id =:= ?RESET_CONFIG_ITEM ->
reset_config(S);
- #wxCommand{type = command_menu_selected} when Id =:= ?UNDO_CONFIG_ITEM ->
+ #wxCommand{type = command_menu_selected}
+ when Id =:= ?UNDO_CONFIG_ITEM ->
undo_config(S);
- #wxCommand{type = command_menu_selected} when Id =:= ?LOAD_CONFIG_ITEM ->
+ #wxCommand{type = command_menu_selected}
+ when Id =:= ?LOAD_CONFIG_ITEM ->
load_config(S);
- #wxCommand{type = command_menu_selected} when Id =:= ?SAVE_CONFIG_NODEF_NODER_ITEM ->
+ #wxCommand{type = command_menu_selected}
+ when Id =:= ?SAVE_CONFIG_NODEF_NODER_ITEM ->
save_config(S, false, false);
- #wxCommand{type = command_menu_selected} when Id =:= ?SAVE_CONFIG_NODEF_DER_ITEM ->
+ #wxCommand{type = command_menu_selected}
+ when Id =:= ?SAVE_CONFIG_NODEF_DER_ITEM ->
save_config(S, false, true);
#wxCommand{type = command_menu_selected} when Id =:= ?SAVE_CONFIG_DEF_NODER_ITEM ->
save_config(S, true, false);
- #wxCommand{type = command_menu_selected} when Id =:= ?SAVE_CONFIG_DEF_DER_ITEM ->
+ #wxCommand{type = command_menu_selected}
+ when Id =:= ?SAVE_CONFIG_DEF_DER_ITEM ->
save_config(S, true, true);
- #wxCommand{type = command_menu_selected} when Id =:= ?GEN_REL_FILES_ITEM ->
+ #wxCommand{type = command_menu_selected}
+ when Id =:= ?GEN_REL_FILES_ITEM ->
gen_rel_files(S);
- #wxCommand{type = command_menu_selected} when Id =:= ?GEN_TARGET_ITEM ->
+ #wxCommand{type = command_menu_selected}
+ when Id =:= ?GEN_TARGET_ITEM ->
gen_target(S);
- #wxCommand{type = command_menu_selected} when UserData =:= main_window, Id =:= ?CONTENTS_ITEM ->
+ #wxCommand{type = command_menu_selected}
+ when UserData =:= main_window, Id =:= ?CONTENTS_ITEM ->
{file, BeamFile} = code:is_loaded(?MODULE),
EbinDir = filename:dirname(BeamFile),
AppDir = filename:dirname(EbinDir),
@@ -735,16 +793,17 @@ handle_event(S, #wx{id = Id, obj= ObjRef, userData = UserData, event = Event} =
Url = "file://" ++ filename:absname(HelpFile),
wx_misc:launchDefaultBrowser(Url),
S;
- #wxCommand{type = command_menu_selected} when UserData =:= main_window, Id =:= ?ABOUT_ITEM ->
- AboutStr = "Reltool is a release management tool. It analyses a given"
- " Erlang/OTP installation and determines various dependencies"
- " between applications. The graphical frontend depicts the"
- " dependencies and enables interactive customization of a"
- " target system. The backend provides a batch interface"
- " for generation of customized target systems.",
- MD = wxMessageDialog:new(S#state.frame,
+ #wxCommand{type = command_menu_selected}
+ when UserData =:= main_window, Id =:= ?ABOUT_ITEM ->
+ AboutStr = "Reltool is a release management tool. It analyses a "
+ " given Erlang/OTP installation and determines various "
+ " dependencies between applications. The graphical frontend "
+ " depicts the dependencies and enables interactive "
+ " customization of a target system. The backend provides a "
+ " batch interface for generation of customized target systems.",
+ MD = wxMessageDialog:new(S#state.frame,
AboutStr,
- [{style, ?wxOK bor ?wxICON_INFORMATION},
+ [{style, ?wxOK bor ?wxICON_INFORMATION},
{caption, "About Reltool"}]),
wxMessageDialog:showModal(MD),
wxMessageDialog:destroy(MD),
@@ -758,7 +817,8 @@ handle_event(S, #wx{id = Id, obj= ObjRef, userData = UserData, event = Event} =
wxWindow:setFocus(ObjRef),
S;
_ ->
- case wxNotebook:getPageText(S#state.book, wxNotebook:getSelection(S#state.book)) of
+ case wxNotebook:getPageText(S#state.book,
+ wxNotebook:getSelection(S#state.book)) of
?APP_PAGE -> handle_app_event(S, Event, ObjRef, UserData);
?LIB_PAGE -> handle_source_event(S, Event, ObjRef, UserData);
?SYS_PAGE -> handle_system_event(S, Event, ObjRef, UserData);
@@ -768,13 +828,17 @@ handle_event(S, #wx{id = Id, obj= ObjRef, userData = UserData, event = Event} =
handle_popup_event(S, _Type, 0, _ObjRef, _UserData, _Str) ->
S#state{popup_menu = undefined};
-handle_popup_event(#state{popup_menu = #root_popup{dir = OldDir, choices = Choices},
+handle_popup_event(#state{popup_menu = #root_popup{dir = OldDir,
+ choices = Choices},
sys = Sys} = S,
_Type, Pos, _ObjRef, _UserData, _Str) ->
case lists:nth(Pos, Choices) of
edit ->
Style = ?wxFD_OPEN bor ?wxFD_FILE_MUST_EXIST,
- case select_dir(S#state.frame, "Change root directory", OldDir, Style) of
+ case select_dir(S#state.frame,
+ "Change root directory",
+ OldDir,
+ Style) of
{ok, NewDir} when NewDir =:= OldDir ->
%% Same dir.Ignore.
S#state{popup_menu = undefined};
@@ -785,7 +849,8 @@ handle_popup_event(#state{popup_menu = #root_popup{dir = OldDir, choices = Choic
S#state{popup_menu = undefined}
end
end;
-handle_popup_event(#state{popup_menu = #lib_popup{dir = OldDir, choices = Choices},
+handle_popup_event(#state{popup_menu = #lib_popup{dir = OldDir,
+ choices = Choices},
sys = Sys} = S,
_Type, Pos, _ObjRef, _UserData, _Str) ->
case lists:nth(Pos, Choices) of
@@ -801,14 +866,18 @@ handle_popup_event(#state{popup_menu = #lib_popup{dir = OldDir, choices = Choice
false ->
LibDirs = Sys#sys.lib_dirs ++ [NewDir],
Sys2 = Sys#sys{lib_dirs = LibDirs},
- do_set_sys(S#state{popup_menu = undefined, sys = Sys2})
+ do_set_sys(S#state{popup_menu = undefined,
+ sys = Sys2})
end;
cancel ->
S#state{popup_menu = undefined}
end;
edit ->
Style = ?wxFD_OPEN bor ?wxFD_FILE_MUST_EXIST,
- case select_dir(S#state.frame, "Change library directory", OldDir, Style) of
+ case select_dir(S#state.frame,
+ "Change library directory",
+ OldDir,
+ Style) of
{ok, NewDir} ->
case lists:member(NewDir, Sys#sys.lib_dirs) of
true ->
@@ -820,7 +889,8 @@ handle_popup_event(#state{popup_menu = #lib_popup{dir = OldDir, choices = Choice
lists:splitwith(Pred, Sys#sys.lib_dirs),
LibDirs2 = Before ++ [NewDir | After],
Sys2 = Sys#sys{lib_dirs = LibDirs2},
- do_set_sys(S#state{popup_menu = undefined, sys = Sys2})
+ do_set_sys(S#state{popup_menu = undefined,
+ sys = Sys2})
end;
cancel ->
S#state{popup_menu = undefined}
@@ -828,14 +898,15 @@ handle_popup_event(#state{popup_menu = #lib_popup{dir = OldDir, choices = Choice
delete ->
LibDirs = Sys#sys.lib_dirs -- [OldDir],
Sys2 = Sys#sys{lib_dirs = LibDirs},
- do_set_sys(S#state{popup_menu = undefined, sys = Sys2})
+ do_set_sys(S#state{popup_menu = undefined, sys = Sys2})
end;
-handle_popup_event(#state{popup_menu = #escript_popup{file = OldFile, choices = Choices},
+handle_popup_event(#state{popup_menu = #escript_popup{file = OldFile,
+ choices = Choices},
sys = Sys} = S,
_Type, Pos, _ObjRef, _UserData, _Str) ->
case lists:nth(Pos, Choices) of
add ->
- OldFile2 =
+ OldFile2 =
case OldFile of
undefined ->
{ok, Cwd} = file:get_cwd(),
@@ -844,7 +915,10 @@ handle_popup_event(#state{popup_menu = #escript_popup{file = OldFile, choices =
OldFile
end,
Style = ?wxFD_OPEN bor ?wxFD_FILE_MUST_EXIST,
- case select_file(S#state.frame, "Select an escript file to add", OldFile2, Style) of
+ case select_file(S#state.frame,
+ "Select an escript file to add",
+ OldFile2,
+ Style) of
{ok, NewFile} ->
case lists:member(NewFile, Sys#sys.escripts) of
true ->
@@ -860,7 +934,10 @@ handle_popup_event(#state{popup_menu = #escript_popup{file = OldFile, choices =
end;
edit ->
Style = ?wxFD_OPEN bor ?wxFD_FILE_MUST_EXIST,
- case select_file(S#state.frame, "Change escript file name", OldFile, Style) of
+ case select_file(S#state.frame,
+ "Change escript file name",
+ OldFile,
+ Style) of
{ok, NewFile} ->
case lists:member(NewFile, Sys#sys.escripts) of
true ->
@@ -868,10 +945,12 @@ handle_popup_event(#state{popup_menu = #escript_popup{file = OldFile, choices =
S#state{popup_menu = undefined};
false ->
Pred = fun(E) -> E =/= OldFile end,
- {Before, [_| After]} = lists:splitwith(Pred, Sys#sys.escripts),
+ {Before, [_| After]} =
+ lists:splitwith(Pred, Sys#sys.escripts),
Escripts2 = Before ++ [NewFile | After],
Sys2 = Sys#sys{escripts = Escripts2},
- do_set_sys(S#state{popup_menu = undefined, sys = Sys2})
+ do_set_sys(S#state{popup_menu = undefined,
+ sys = Sys2})
end;
cancel ->
S#state{popup_menu = undefined}
@@ -879,25 +958,28 @@ handle_popup_event(#state{popup_menu = #escript_popup{file = OldFile, choices =
delete ->
Escripts = Sys#sys.escripts -- [OldFile],
Sys2 = Sys#sys{escripts = Escripts},
- do_set_sys(S#state{popup_menu = undefined, sys = Sys2})
+ do_set_sys(S#state{popup_menu = undefined, sys = Sys2})
end.
handle_system_event(#state{sys = Sys} = S,
- #wxCommand{type = command_radiobox_selected, cmdString = Choice},
+ #wxCommand{type = command_radiobox_selected,
+ cmdString = Choice},
_ObjRef,
config_mod_cond) ->
ModCond = reltool_utils:list_to_mod_cond(Choice),
Sys2 = Sys#sys{mod_cond = ModCond},
do_set_sys(S#state{sys = Sys2});
handle_system_event(#state{sys = Sys} = S,
- #wxCommand{type = command_radiobox_selected, cmdString = Choice},
+ #wxCommand{type = command_radiobox_selected,
+ cmdString = Choice},
_ObjRef,
config_incl_cond) ->
AppCond = reltool_utils:list_to_incl_cond(Choice),
Sys2 = Sys#sys{incl_cond = AppCond},
do_set_sys(S#state{sys = Sys2});
handle_system_event(S, Event, ObjRef, UserData) ->
- error_logger:format("~p~p got unexpected wx sys event to ~p with user data: ~p\n\t ~p\n",
+ error_logger:format("~p~p got unexpected wx sys event to ~p "
+ "with user data: ~p\n\t ~p\n",
[?MODULE, self(), ObjRef, UserData, Event]),
S.
@@ -905,7 +987,11 @@ handle_release_event(S, _Event, _ObjRef, UserData) ->
io:format("Release data: ~p\n", [UserData]),
S.
-handle_source_event(S, #wxTree{type = command_tree_item_activated, item = Item}, ObjRef, _UserData) ->
+handle_source_event(S,
+ #wxTree{type = command_tree_item_activated,
+ item = Item},
+ ObjRef,
+ _UserData) ->
case wxTreeCtrl:getItemData(ObjRef, Item) of
#root_data{dir = _Dir} ->
%% io:format("Root dialog: ~p\n", [Dir]),
@@ -921,7 +1007,11 @@ handle_source_event(S, #wxTree{type = command_tree_item_activated, item = Item},
undefined ->
S
end;
-handle_source_event(S, #wxTree{type = command_tree_item_right_click, item = Item}, Tree, _UserData) ->
+handle_source_event(S,
+ #wxTree{type = command_tree_item_right_click,
+ item = Item},
+ Tree,
+ _UserData) ->
case wxTreeCtrl:getItemData(Tree, Item) of
#root_data{dir = Dir} ->
wx:batch(fun() -> root_popup(S, Dir, Tree, Item) end);
@@ -936,18 +1026,28 @@ handle_source_event(S, #wxTree{type = command_tree_item_right_click, item = Item
S
end.
-handle_app_event(S, #wxList{type = command_list_item_activated, itemIndex = Pos}, ListCtrl, _UserData) ->
+handle_app_event(S,
+ #wxList{type = command_list_item_activated,
+ itemIndex = Pos},
+ ListCtrl,
+ _UserData) ->
AppName = wxListCtrl:getItemText(ListCtrl, Pos),
do_open_app(S, AppName);
-handle_app_event(S, #wxCommand{type = command_button_clicked}, _ObjRef, {app_button, Action, ListCtrl}) ->
+handle_app_event(S,
+ #wxCommand{type = command_button_clicked},
+ _ObjRef,
+ {app_button, Action, ListCtrl}) ->
Items = reltool_utils:get_items(ListCtrl),
handle_app_button(S, Items, Action);
handle_app_event(S, Event, ObjRef, UserData) ->
- error_logger:format("~p~p got unexpected wx app event to ~p with user data: ~p\n\t ~p\n",
+ error_logger:format("~p~p got unexpected wx app event to "
+ "~p with user data: ~p\n\t ~p\n",
[?MODULE, self(), ObjRef, UserData, Event]),
S.
-handle_app_button(#state{server_pid = ServerPid, app_wins = AppWins} = S, Items, Action) ->
+handle_app_button(#state{server_pid = ServerPid, app_wins = AppWins} = S,
+ Items,
+ Action) ->
NewApps = [move_app(S, Item, Action) || Item <- Items],
case reltool_server:set_apps(ServerPid, NewApps) of
{ok, []} ->
@@ -967,9 +1067,9 @@ do_set_sys(#state{sys = Sys, server_pid = ServerPid, status_bar = Bar} = S) ->
check_and_refresh(S, Status).
move_app(S, {_ItemNo, AppBase}, Action) ->
- {AppName, _Vsn} = reltool_utils:split_app_name(AppBase),
+ {AppName, _Vsn} = reltool_utils:split_app_name(AppBase),
{ok, OldApp} = reltool_server:get_app(S#state.server_pid, AppName),
- AppCond =
+ AppCond =
case Action of
whitelist_add ->
case OldApp#app.incl_cond of
@@ -979,12 +1079,13 @@ move_app(S, {_ItemNo, AppBase}, Action) ->
end;
whitelist_del ->
undefined;
- blacklist_add ->
+ blacklist_add ->
exclude;
blacklist_del ->
undefined;
_ ->
- error_logger:format("~p~p got unexpected app button event: ~p ~p\n",
+ error_logger:format("~p~p got unexpected app "
+ "button event: ~p ~p\n",
[?MODULE, self(), Action, AppBase]),
OldApp#app.incl_cond
end,
@@ -1047,14 +1148,21 @@ do_redraw_apps(ListCtrl, Apps, OkImage, ErrImage) ->
ImageApps = lists:map(AddImage, Apps),
Show =
fun({ImageId, Text, App}, {Row, ModCount, Items}) ->
- wxListCtrl:insertItem(ListCtrl, Row, ""),
- if (Row rem 2) =:= 0 ->
- wxListCtrl:setItemBackgroundColour(ListCtrl, Row, {240,240,255});
+ wxListCtrl:insertItem(ListCtrl, Row, ""),
+ if (Row rem 2) =:= 0 ->
+ wxListCtrl:setItemBackgroundColour(ListCtrl,
+ Row,
+ {240,240,255});
true ->
ignore
end,
- wxListCtrl:setItem(ListCtrl, Row, ?APPS_APP_COL, Text, [{imageId, ImageId}]),
- N = length([M || M <- App#app.mods, M#mod.is_included =:= true]),
+ wxListCtrl:setItem(ListCtrl,
+ Row,
+ ?APPS_APP_COL,
+ Text,
+ [{imageId, ImageId}]),
+ N = length([M || M <- App#app.mods,
+ M#mod.is_included =:= true]),
{Row + 1, ModCount + N, [{Row, Text} | Items]}
end,
{_, N, NewItems} = wx:foldl(Show, {0, 0, []}, lists:sort(ImageApps)),
@@ -1068,8 +1176,10 @@ update_app_graph(S) ->
WhiteNames = [A#app.name || A <- WhiteApps],
DerivedNames = [A#app.name || A <- DerivedApps],
Nodes = WhiteNames ++ DerivedNames,
- %% WhiteUses = [N || A <- WhiteApps, N <- A#app.uses_apps, lists:member(N, Nodes)],
- %% DerivedUses = [N || A <- DerivedApps, N <- A#app.uses_apps, lists:member(N, Nodes)],
+ %% WhiteUses = [N || A <- WhiteApps,
+ %% N <- A#app.uses_apps, lists:member(N, Nodes)],
+ %% DerivedUses = [N || A <- DerivedApps,
+ %% N <- A#app.uses_apps, lists:member(N, Nodes)],
WhiteLinks = [[A#app.name, U] || A <- WhiteApps,
U <- A#app.uses_apps,
@@ -1078,7 +1188,7 @@ update_app_graph(S) ->
DerivedLinks = [[A#app.name, U] || A <- DerivedApps,
U <- A#app.uses_apps,
U =/= A#app.name,
- lists:member(U, Nodes)],
+ lists:member(U, Nodes)],
Links = lists:usort(WhiteLinks ++ DerivedLinks),
%% io:format("Links: ~p\n", [Links]),
Title = lists:concat([?APPLICATION, " - application graph"]),
@@ -1087,8 +1197,12 @@ update_app_graph(S) ->
update_mod_graph(S) ->
{ok, WhiteApps} = reltool_server:get_apps(S#state.server_pid, whitelist),
{ok, DerivedApps} = reltool_server:get_apps(S#state.server_pid, derived),
- WhiteMods = lists:usort([M || A <- WhiteApps, M <- A#app.mods, M#mod.is_included =:= true]),
- DerivedMods = lists:usort([M || A <- DerivedApps, M <- A#app.mods, M#mod.is_included =:= true]),
+ WhiteMods = lists:usort([M || A <- WhiteApps,
+ M <- A#app.mods,
+ M#mod.is_included =:= true]),
+ DerivedMods = lists:usort([M || A <- DerivedApps,
+ M <- A#app.mods,
+ M#mod.is_included =:= true]),
WhiteNames = [M#mod.name || M <- WhiteMods],
DerivedNames = [M#mod.name || M <- DerivedMods],
@@ -1141,7 +1255,10 @@ undo_config(#state{status_bar = Bar} = S) ->
load_config(#state{status_bar = Bar, config_file = OldFile} = S) ->
Style = ?wxFD_OPEN bor ?wxFD_FILE_MUST_EXIST,
- case select_file(S#state.frame, "Select a file to load the configuration from", OldFile, Style) of
+ case select_file(S#state.frame,
+ "Select a file to load the configuration from",
+ OldFile,
+ Style) of
{ok, NewFile} ->
wxStatusBar:setStatusText(Bar, "Processing libraries..."),
Status = reltool_server:load_config(S#state.server_pid, NewFile),
@@ -1151,18 +1268,27 @@ load_config(#state{status_bar = Bar, config_file = OldFile} = S) ->
end.
save_config(#state{config_file = OldFile} = S, InclDefaults, InclDerivates) ->
- Style = ?wxFD_SAVE bor ?wxFD_OVERWRITE_PROMPT,
- case select_file(S#state.frame, "Select a file to save the configuration to", OldFile, Style) of
+ Style = ?wxFD_SAVE bor ?wxFD_OVERWRITE_PROMPT,
+ case select_file(S#state.frame,
+ "Select a file to save the configuration to",
+ OldFile,
+ Style) of
{ok, NewFile} ->
- Status = reltool_server:save_config(S#state.server_pid, NewFile, InclDefaults, InclDerivates),
+ Status = reltool_server:save_config(S#state.server_pid,
+ NewFile,
+ InclDefaults,
+ InclDerivates),
check_and_refresh(S#state{config_file = NewFile}, Status);
cancel ->
S
end.
gen_rel_files(#state{target_dir = OldDir} = S) ->
- Style = ?wxFD_SAVE bor ?wxFD_OVERWRITE_PROMPT,
- case select_dir(S#state.frame, "Select a directory to generate rel, script and boot files to", OldDir, Style) of
+ Style = ?wxFD_SAVE bor ?wxFD_OVERWRITE_PROMPT,
+ case select_dir(S#state.frame,
+ "Select a directory to generate rel, script and boot files to",
+ OldDir,
+ Style) of
{ok, NewDir} ->
Status = reltool_server:gen_rel_files(S#state.server_pid, NewDir),
check_and_refresh(S, Status);
@@ -1171,8 +1297,11 @@ gen_rel_files(#state{target_dir = OldDir} = S) ->
end.
gen_target(#state{target_dir = OldDir} = S) ->
- Style = ?wxFD_SAVE bor ?wxFD_OVERWRITE_PROMPT,
- case select_dir(S#state.frame, "Select a directory to generate a target system to", OldDir, Style) of
+ Style = ?wxFD_SAVE bor ?wxFD_OVERWRITE_PROMPT,
+ case select_dir(S#state.frame,
+ "Select a directory to generate a target system to",
+ OldDir,
+ Style) of
{ok, NewDir} ->
Status = reltool_server:gen_target(S#state.server_pid, NewDir),
check_and_refresh(S#state{target_dir = NewDir}, Status);
@@ -1186,7 +1315,7 @@ select_file(Frame, Message, DefaultFile, Style) ->
{defaultDir, filename:dirname(DefaultFile)},
{defaultFile, filename:basename(DefaultFile)},
{style, Style}]),
- Choice =
+ Choice =
case wxMessageDialog:showModal(Dialog) of
?wxID_CANCEL -> cancel;
?wxID_OK -> {ok, wxFileDialog:getPath(Dialog)}
@@ -1199,7 +1328,7 @@ select_dir(Frame, Message, DefaultDir, Style) ->
[{title, Message},
{defaultPath, DefaultDir},
{style, Style}]),
- Choice =
+ Choice =
case wxMessageDialog:showModal(Dialog) of
?wxID_CANCEL -> cancel;
?wxID_OK -> {ok, wxDirDialog:getPath(Dialog)}
@@ -1229,28 +1358,34 @@ refresh(S) ->
S2 = S#state{sys = Sys},
S3 = redraw_libs(S2),
redraw_apps(S3).
-
+
question_dialog(Question, Details) ->
%% Parent = S#state.frame,
Parent = wx:typeCast(wx:null(), wxWindow),
%% [{style, ?wxYES_NO bor ?wxICON_ERROR bor ?wx}]),
DialogStyle = ?wxRESIZE_BORDER bor ?wxCAPTION bor ?wxSYSTEM_MENU bor
?wxMINIMIZE_BOX bor ?wxMAXIMIZE_BOX bor ?wxCLOSE_BOX,
- Dialog = wxDialog:new(Parent, ?wxID_ANY, "Undo dialog", [{style, DialogStyle}]),
+ Dialog = wxDialog:new(Parent, ?wxID_ANY, "Undo dialog",
+ [{style, DialogStyle}]),
Color = wxWindow:getBackgroundColour(Dialog),
TextStyle = ?wxTE_READONLY bor ?wxTE_MULTILINE bor ?wxHSCROLL,
- Text1 = wxTextCtrl:new(Dialog, ?wxID_ANY, [{style, ?wxTE_READONLY bor ?wxBORDER_NONE}]),
+ Text1 = wxTextCtrl:new(Dialog, ?wxID_ANY,
+ [{style, ?wxTE_READONLY bor ?wxBORDER_NONE}]),
wxWindow:setBackgroundColour(Text1, Color),
wxTextCtrl:appendText(Text1, Question),
- Text2 = wxTextCtrl:new(Dialog, ?wxID_ANY, [{size, {600, 400}}, {style, TextStyle}]),
+ Text2 = wxTextCtrl:new(Dialog, ?wxID_ANY,
+ [{size, {600, 400}}, {style, TextStyle}]),
wxWindow:setBackgroundColour(Text2, Color),
wxTextCtrl:appendText(Text2, Details),
%% wxDialog:setAffirmativeId(Dialog, ?wxID_YES),
%% wxDialog:setEscapeId(Dialog, ?wxID_NO),
Sizer = wxBoxSizer:new(?wxVERTICAL),
wxSizer:add(Sizer, Text1, [{border, 2}, {flag, ?wxEXPAND}]),
- wxSizer:add(Sizer, Text2, [{border, 2}, {flag, ?wxEXPAND}, {proportion, 1}]),
- ButtSizer = wxDialog:createStdDialogButtonSizer(Dialog, ?wxOK bor ?wxCANCEL),
+ wxSizer:add(Sizer, Text2, [{border, 2},
+ {flag, ?wxEXPAND},
+ {proportion, 1}]),
+ ButtSizer = wxDialog:createStdDialogButtonSizer(Dialog,
+ ?wxOK bor ?wxCANCEL),
wxSizer:add(Sizer, ButtSizer, [{border, 2}, {flag, ?wxEXPAND}]),
wxPanel:setSizer(Dialog, Sizer),
wxSizer:fit(Sizer, Dialog),
diff --git a/lib/reltool/src/reltool_target.erl b/lib/reltool/src/reltool_target.erl
index 6d85a98d9f..e079a02f3c 100644
--- a/lib/reltool/src/reltool_target.erl
+++ b/lib/reltool/src/reltool_target.erl
@@ -22,7 +22,7 @@
-export([
gen_config/2,
gen_app/1,
- gen_rel/2,
+ gen_rel/2,
gen_rel_files/2,
gen_boot/1,
gen_script/4,
@@ -55,7 +55,9 @@ kernel_processes(KernelApp) ->
[
{kernelProcess, heart, {heart, start, []}},
{kernelProcess, error_logger , {error_logger, start_link, []}},
- {kernelProcess, application_controller, {application_controller, start, [KernelApp]}}
+ {kernelProcess,
+ application_controller,
+ {application_controller, start, [KernelApp]}}
].
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -82,120 +84,126 @@ gen_config(#sys{root_dir = RootDir,
app_type = AppType,
app_file = AppFile,
debug_info = DebugInfo},
- InclDefaults) ->
- ErtsItems =
+ InclDefs) ->
+ ErtsItems =
case lists:keysearch(erts, #app.name, Apps) of
{value, Erts} ->
- [{erts, gen_config(Erts, InclDefaults)}];
+ [{erts, gen_config(Erts, InclDefs)}];
false ->
[]
end,
AppsItems =
- [{app, A#app.name, gen_config(A, InclDefaults)}
- || A <- Apps,
+ [{app, A#app.name, gen_config(A, InclDefs)}
+ || A <- Apps,
A#app.name =/= ?MISSING_APP,
A#app.name =/= erts,
A#app.is_included =:= true,
A#app.is_escript =/= true],
- EscriptItems = [{escript, A#app.active_dir, emit(incl_cond, A#app.incl_cond, undefined, InclDefaults)}
+ EscriptItems = [{escript,
+ A#app.active_dir,
+ emit(incl_cond, A#app.incl_cond, undefined, InclDefs)}
|| A <- Apps, A#app.is_escript],
DefaultRels = reltool_utils:default_rels(),
RelsItems =
- case {[{rel, R#rel.name, R#rel.vsn, gen_config(R, InclDefaults)} || R <- Rels],
- [{rel, R#rel.name, R#rel.vsn, gen_config(R, InclDefaults)} || R <- DefaultRels]} of
+ case {[{rel, R#rel.name, R#rel.vsn, gen_config(R, InclDefs)} ||
+ R <- Rels],
+ [{rel, R#rel.name, R#rel.vsn, gen_config(R, InclDefs)} ||
+ R <- DefaultRels]} of
{RI, RI} -> [];
{RI, _} -> RI
end,
X = fun(List) -> [Re || #regexp{source = Re} <- List] end,
{sys,
- emit(root_dir, RootDir, code:root_dir(), InclDefaults) ++
- emit(lib_dirs, LibDirs, ?DEFAULT_LIBS, InclDefaults) ++
+ emit(root_dir, RootDir, code:root_dir(), InclDefs) ++
+ emit(lib_dirs, LibDirs, ?DEFAULT_LIBS, InclDefs) ++
EscriptItems ++
- emit(mod_cond, ModCond, ?DEFAULT_MOD_COND, InclDefaults) ++
- emit(incl_cond, AppCond, ?DEFAULT_INCL_COND, InclDefaults) ++
+ emit(mod_cond, ModCond, ?DEFAULT_MOD_COND, InclDefs) ++
+ emit(incl_cond, AppCond, ?DEFAULT_INCL_COND, InclDefs) ++
ErtsItems ++
AppsItems ++
- emit(boot_rel, BootRel, ?DEFAULT_REL_NAME, InclDefaults) ++
+ emit(boot_rel, BootRel, ?DEFAULT_REL_NAME, InclDefs) ++
RelsItems ++
- emit(emu_name, EmuName, ?DEFAULT_EMU_NAME, InclDefaults) ++
- emit(relocatable, Relocatable, ?DEFAULT_RELOCATABLE, InclDefaults) ++
- emit(profile, Profile, ?DEFAULT_PROFILE, InclDefaults) ++
- emit(incl_sys_filters, X(InclSysFiles), ?DEFAULT_INCL_SYS_FILTERS, InclDefaults) ++
- emit(excl_sys_filters, X(ExclSysFiles), ?DEFAULT_EXCL_SYS_FILTERS, InclDefaults) ++
- emit(incl_app_filters, X(InclAppFiles), ?DEFAULT_INCL_APP_FILTERS, InclDefaults) ++
- emit(excl_app_filters, X(ExclAppFiles), ?DEFAULT_EXCL_APP_FILTERS, InclDefaults) ++
- emit(incl_archive_filters, X(InclArchiveDirs), ?DEFAULT_INCL_ARCHIVE_FILTERS, InclDefaults) ++
- emit(excl_archive_filters, X(ExclArchiveDirs), ?DEFAULT_EXCL_ARCHIVE_FILTERS, InclDefaults) ++
- emit(archive_opts, ArchiveOpts, ?DEFAULT_ARCHIVE_OPTS, InclDefaults) ++
- emit(app_type, AppType, ?DEFAULT_APP_TYPE, InclDefaults) ++
- emit(app_file, AppFile, ?DEFAULT_APP_FILE, InclDefaults) ++
- emit(debug_info, DebugInfo, ?DEFAULT_DEBUG_INFO, InclDefaults)};
-gen_config(#app{name = _Name,
- mod_cond = ModCond,
- incl_cond = AppCond,
- debug_info = DebugInfo,
- app_file = AppFile,
- incl_app_filters = InclAppFiles,
- excl_app_filters = ExclAppFiles,
+ emit(emu_name, EmuName, ?DEFAULT_EMU_NAME, InclDefs) ++
+ emit(relocatable, Relocatable, ?DEFAULT_RELOCATABLE, InclDefs) ++
+ emit(profile, Profile, ?DEFAULT_PROFILE, InclDefs) ++
+ emit(incl_sys_filters, X(InclSysFiles), ?DEFAULT_INCL_SYS_FILTERS, InclDefs) ++
+ emit(excl_sys_filters, X(ExclSysFiles), ?DEFAULT_EXCL_SYS_FILTERS, InclDefs) ++
+ emit(incl_app_filters, X(InclAppFiles), ?DEFAULT_INCL_APP_FILTERS, InclDefs) ++
+ emit(excl_app_filters, X(ExclAppFiles), ?DEFAULT_EXCL_APP_FILTERS, InclDefs) ++
+ emit(incl_archive_filters, X(InclArchiveDirs), ?DEFAULT_INCL_ARCHIVE_FILTERS, InclDefs) ++
+ emit(excl_archive_filters, X(ExclArchiveDirs), ?DEFAULT_EXCL_ARCHIVE_FILTERS, InclDefs) ++
+ emit(archive_opts, ArchiveOpts, ?DEFAULT_ARCHIVE_OPTS, InclDefs) ++
+ emit(app_type, AppType, ?DEFAULT_APP_TYPE, InclDefs) ++
+ emit(app_file, AppFile, ?DEFAULT_APP_FILE, InclDefs) ++
+ emit(debug_info, DebugInfo, ?DEFAULT_DEBUG_INFO, InclDefs)};
+gen_config(#app{name = _Name,
+ mod_cond = ModCond,
+ incl_cond = AppCond,
+ debug_info = DebugInfo,
+ app_file = AppFile,
+ incl_app_filters = InclAppFiles,
+ excl_app_filters = ExclAppFiles,
incl_archive_filters = InclArchiveDirs,
excl_archive_filters = ExclArchiveDirs,
- archive_opts = ArchiveOpts,
+ archive_opts = ArchiveOpts,
use_selected_vsn = UseSelected,
vsn = Vsn,
mods = Mods},
- InclDefaults) ->
- emit(mod_cond, ModCond, undefined, InclDefaults) ++
- emit(incl_cond, AppCond, undefined, InclDefaults) ++
- emit(debug_info, DebugInfo, undefined, InclDefaults) ++
- emit(app_file, AppFile, undefined, InclDefaults) ++
- emit(incl_app_filters, InclAppFiles, undefined, InclDefaults) ++
- emit(excl_app_filters, ExclAppFiles, undefined, InclDefaults) ++
- emit(incl_archive_filters, InclArchiveDirs, undefined, InclDefaults) ++
- emit(excl_archive_filters, ExclArchiveDirs, undefined, InclDefaults) ++
- emit(archive_opts, ArchiveOpts, undefined, InclDefaults) ++
- emit(vsn, Vsn, undefined, InclDefaults orelse UseSelected =/= true) ++
- [{mod, M#mod.name, gen_config(M, InclDefaults)} || M <- Mods, M#mod.is_included =:= true];
+ InclDefs) ->
+ emit(mod_cond, ModCond, undefined, InclDefs) ++
+ emit(incl_cond, AppCond, undefined, InclDefs) ++
+ emit(debug_info, DebugInfo, undefined, InclDefs) ++
+ emit(app_file, AppFile, undefined, InclDefs) ++
+ emit(incl_app_filters, InclAppFiles, undefined, InclDefs) ++
+ emit(excl_app_filters, ExclAppFiles, undefined, InclDefs) ++
+ emit(incl_archive_filters, InclArchiveDirs, undefined, InclDefs) ++
+ emit(excl_archive_filters, ExclArchiveDirs, undefined, InclDefs) ++
+ emit(archive_opts, ArchiveOpts, undefined, InclDefs) ++
+ emit(vsn, Vsn, undefined, InclDefs orelse UseSelected =/= true) ++
+ [{mod, M#mod.name, gen_config(M, InclDefs)} ||
+ M <- Mods,
+ M#mod.is_included =:= true];
gen_config(#mod{name = _Name,
incl_cond = AppCond,
debug_info = DebugInfo},
- InclDefaults) ->
- emit(incl_cond, AppCond, undefined, InclDefaults) ++
- emit(debug_info, DebugInfo, undefined, InclDefaults);
+ InclDefs) ->
+ emit(incl_cond, AppCond, undefined, InclDefs) ++
+ emit(debug_info, DebugInfo, undefined, InclDefs);
gen_config(#rel{name = _Name,
vsn = _Vsn,
rel_apps = RelApps},
- InclDefaults) ->
- [gen_config(RA, InclDefaults) || RA <- RelApps];
+ InclDefs) ->
+ [gen_config(RA, InclDefs) || RA <- RelApps];
gen_config(#rel_app{name = Name,
app_type = Type,
incl_apps = InclApps},
- _InclDefaults) ->
+ _InclDefs) ->
case {Type, InclApps} of
{undefined, []} -> Name;
{undefined, _} -> {Name, InclApps};
{_, []} -> {Name, Type};
{_, _} -> {Name, Type, InclApps}
end;
-gen_config({Tag, Val}, InclDefaults) ->
- emit(Tag, Val, undefined, InclDefaults);
-gen_config([], _InclDefaults) ->
+gen_config({Tag, Val}, InclDefs) ->
+ emit(Tag, Val, undefined, InclDefs);
+gen_config([], _InclDefs) ->
[];
-gen_config([H | T], InclDefaults) ->
- lists:flatten([gen_config(H, InclDefaults), gen_config(T, InclDefaults)]).
+gen_config([H | T], InclDefs) ->
+ lists:flatten([gen_config(H, InclDefs), gen_config(T, InclDefs)]).
-emit(Tag, Val, Default, InclDefaults) ->
+emit(Tag, Val, Default, InclDefs) ->
if
Val == undefined -> [];
- InclDefaults -> [{Tag, Val}];
+ InclDefs -> [{Tag, Val}];
Val =/= Default -> [{Tag, Val}];
true -> []
- end.
+ end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Generate the contents of an app file
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-gen_app(#app{name = Name,
+gen_app(#app{name = Name,
info = #app_info{description = Desc,
id = Id,
vsn = Vsn,
@@ -234,19 +242,20 @@ gen_app(#app{name = Name,
gen_rel(#rel{name = RelName, vsn = RelVsn, rel_apps = RelApps},
#sys{apps = Apps}) ->
{value, Erts} = lists:keysearch(erts, #app.name, Apps),
- {release,
+ {release,
{RelName, RelVsn},
{erts, Erts#app.vsn},
[app_to_rel(RA, Apps ) || RA <- RelApps]}.
-app_to_rel(#rel_app{name = Name, app_type = Type, incl_apps = InclApps}, Apps) ->
+app_to_rel(#rel_app{name = Name, app_type = Type, incl_apps = InclApps},
+ Apps) ->
{value, #app{vsn = Vsn}} = lists:keysearch(Name, #app.name, Apps),
case {Type, InclApps} of
{undefined, []} -> {Name, Vsn};
{undefined, _} -> {Name, Vsn, InclApps};
{_, []} -> {Name, Vsn, Type};
{_, _} -> {Name, Vsn, Type, InclApps}
- end.
+ end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Generate the contents of a boot file
@@ -262,7 +271,7 @@ gen_boot({script, {_, _}, _} = Script) ->
gen_script(Rel, Sys, PathFlag, Variables) ->
try
do_gen_script(Rel, Sys, PathFlag, Variables)
- catch
+ catch
throw:{error, Text} ->
{error, Text}
end.
@@ -279,7 +288,9 @@ do_gen_script(#rel{name = RelName, vsn = RelVsn, rel_apps = RelApps},
SortedApps = sort_apps(MergedApps),
{value, KernelApp} = lists:keysearch(kernel, #app.name, SortedApps),
- InclApps = lists:append([I || #app{info = #app_info{incl_apps = I}} <- SortedApps]),
+ InclApps =
+ lists:append([I ||
+ #app{info = #app_info{incl_apps = I}} <- SortedApps]),
%% Create the script
DeepList =
@@ -312,9 +323,9 @@ do_gen_script(#rel{name = RelName, vsn = RelVsn, rel_apps = RelApps},
%% Start applications
[{apply, {application, start_boot, [Name, Type]}} ||
- #app{name = Name, app_type = Type} <- SortedApps,
- Type =/= none,
- Type =/= load,
+ #app{name = Name, app_type = Type} <- SortedApps,
+ Type =/= none,
+ Type =/= load,
not lists:member(Name, InclApps)],
%% Apply user specific customizations
@@ -323,7 +334,9 @@ do_gen_script(#rel{name = RelName, vsn = RelVsn, rel_apps = RelApps},
],
{ok, {script, {RelName, RelVsn}, lists:flatten(DeepList)}}.
-merge_app(#rel_app{name = Name, app_type = Type, incl_apps = RelIncl}, Apps, DefaultType) ->
+merge_app(#rel_app{name = Name, app_type = Type, incl_apps = RelIncl},
+ Apps,
+ DefaultType) ->
{value, App} = lists:keysearch(Name, #app.name, Apps),
Type2 =
case {Type, App#app.app_type} of
@@ -334,10 +347,12 @@ merge_app(#rel_app{name = Name, app_type = Type, incl_apps = RelIncl}, Apps, Def
Info = App#app.info,
case RelIncl -- Info#app_info.incl_apps of
[] ->
- App#app{app_type = Type2, info = Info#app_info{incl_apps = RelIncl}};
+ App#app{app_type = Type2,
+ info = Info#app_info{incl_apps = RelIncl}};
BadIncl ->
- reltool_utils:throw_error("~p: These applications are missing as "
- "included_applications in the app file: ~p\n",
+ reltool_utils:throw_error("~p: These applications are "
+ "missing as included_applications "
+ "in the app file: ~p\n",
[Name, BadIncl])
end.
@@ -359,7 +374,7 @@ load_app_mods(#app{mods = Mods} = App, Mand, PathFlag, Variables) ->
Subs ->
[{Subs, [M]}|[{Last,Acc}|Rest]]
end
- end,
+ end,
[{[],
[]}],
PartNames),
@@ -381,17 +396,26 @@ load_app_mods(#app{mods = Mods} = App, Mand, PathFlag, Variables) ->
%% Mod. by mbj
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-sort_apps(Apps) ->
+sort_apps(Apps) ->
sort_apps(Apps, [], [], []).
-sort_apps([#app{name = Name, info = Info} = App | Apps], Missing, Circular, Visited) ->
- {Uses, Apps1, NotFnd1} = find_all(Name, Info#app_info.applications, Apps, Visited, [], []),
- {Incs, Apps2, NotFnd2} = find_all(Name, lists:reverse(Info#app_info.incl_apps),
- Apps1, Visited, [], []),
-
+sort_apps([#app{name = Name, info = Info} = App | Apps],
+ Missing,
+ Circular,
+ Visited) ->
+ {Uses, Apps1, NotFnd1} =
+ find_all(Name, Info#app_info.applications, Apps, Visited, [], []),
+ {Incs, Apps2, NotFnd2} =
+ find_all(Name,
+ lists:reverse(Info#app_info.incl_apps),
+ Apps1,
+ Visited,
+ [],
+ []),
+
Missing1 = NotFnd1 ++ NotFnd2 ++ Missing,
case Uses ++ Incs of
- [] ->
+ [] ->
%% No more app that must be started before this one is
%% found; they are all already taken care of (and present
%% in Visited list)
@@ -401,8 +425,8 @@ sort_apps([#app{name = Name, info = Info} = App | Apps], Missing, Circular, Visi
%% Check if we have already taken care of some app in L,
%% in that case we have a circular dependency.
NewCircular = [N1 || N1 <- L, N2 <- Visited, N1 =:= N2],
- Circular1 = case NewCircular of
- [] -> Circular;
+ Circular1 = case NewCircular of
+ [] -> Circular;
_ -> [Name | NewCircular] ++ Circular
end,
%% L must be started before N, try again, with all apps
@@ -414,9 +438,11 @@ sort_apps([], [], [], _) ->
[];
sort_apps([], Missing, [], _) ->
%% this has already been checked before, but as we have the info...
- reltool_utils:throw_error("Undefined applications: ~p\n", [make_set(Missing)]);
+ reltool_utils:throw_error("Undefined applications: ~p\n",
+ [make_set(Missing)]);
sort_apps([], [], Circular, _) ->
- reltool_utils:throw_error("Circular dependencies: ~p\n", [make_set(Circular)]);
+ reltool_utils:throw_error("Circular dependencies: ~p\n",
+ [make_set(Circular)]);
sort_apps([], Missing, Circular, _) ->
reltool_utils:throw_error("Circular dependencies: ~p\n"
"Undefined applications: ~p\n",
@@ -431,24 +457,49 @@ find_all(CheckingApp, [Name | Names], Apps, Visited, Found, NotFound) ->
true ->
case lists:member(Name, Visited) of
true ->
- find_all(CheckingApp, Names, Apps, Visited, Found, NotFound);
+ find_all(CheckingApp,
+ Names,
+ Apps,
+ Visited,
+ Found,
+ NotFound);
false ->
- find_all(CheckingApp, Names, Apps, Visited, Found, [Name | NotFound])
+ find_all(CheckingApp,
+ Names,
+ Apps,
+ Visited,
+ Found,
+ [Name | NotFound])
end;
false ->
- find_all(CheckingApp, Names, Apps -- [App], Visited, [App|Found], NotFound)
+ find_all(CheckingApp,
+ Names,
+ Apps -- [App],
+ Visited,
+ [App|Found],
+ NotFound)
end;
false ->
case lists:member(Name, Visited) of
true ->
- find_all(CheckingApp, Names, Apps, Visited, Found, NotFound);
+ find_all(CheckingApp,
+ Names,
+ Apps,
+ Visited,
+ Found,
+ NotFound);
false ->
- find_all(CheckingApp, Names, Apps, Visited, Found, [Name|NotFound])
+ find_all(CheckingApp,
+ Names,
+ Apps,
+ Visited,
+ Found,
+ [Name|NotFound])
end
end;
find_all(_CheckingApp, [], Apps, _Visited, Found, NotFound) ->
{Found, Apps, NotFound}.
-
+
del_apps([Name | Names], Apps) ->
del_apps(Names, lists:keydelete(Name, #app.name, Apps));
del_apps([], Apps) ->
@@ -470,7 +521,9 @@ create_path(Apps, PathFlag, Variables) ->
%% (The otp_build flag is only used for OTP internal system make)
cr_path(#app{label = Label}, true, []) ->
filename:join(["$ROOT", "lib", Label, "ebin"]);
-cr_path(#app{name = Name, vsn = Vsn, label = Label, active_dir = Dir}, true, Variables) ->
+cr_path(#app{name = Name, vsn = Vsn, label = Label, active_dir = Dir},
+ true,
+ Variables) ->
Tail = [Label, "ebin"],
case variable_dir(Dir, atom_to_list(Name), Vsn, Variables) of
{ok, VarDir} ->
@@ -542,7 +595,7 @@ gen_rel_files(Sys, TargetDir) ->
try
Spec = spec_rel_files(Sys),
eval_spec(Spec, Sys#sys.root_dir, TargetDir)
- catch
+ catch
throw:{error, Text} ->
{error, Text}
end.
@@ -579,15 +632,15 @@ gen_target(Sys, TargetDir) ->
try
Spec = do_gen_spec(Sys),
eval_spec(Spec, Sys#sys.root_dir, TargetDir)
- catch
+ catch
throw:{error, Text} ->
{error, Text}
end.
-
+
gen_spec(Sys) ->
try
{ok, do_gen_spec(Sys)}
- catch
+ catch
throw:{error, Text} ->
{error, Text}
end.
@@ -598,14 +651,16 @@ do_gen_spec(#sys{root_dir = RootDir,
relocatable = Relocatable,
apps = Apps} = Sys) ->
{create_dir, _, SysFiles} = spec_dir(RootDir),
- {ExclRegexps2, SysFiles2} = strip_sys_files(Relocatable, SysFiles, Apps, ExclRegexps),
+ {ExclRegexps2, SysFiles2} =
+ strip_sys_files(Relocatable, SysFiles, Apps, ExclRegexps),
RelFiles = spec_rel_files(Sys),
- {InclRegexps2, BinFiles} = spec_bin_files(Sys, SysFiles, SysFiles2, RelFiles, InclRegexps),
+ {InclRegexps2, BinFiles} =
+ spec_bin_files(Sys, SysFiles, SysFiles2, RelFiles, InclRegexps),
LibFiles = spec_lib_files(Sys),
{BootVsn, StartFile} = spec_start_file(Sys),
SysFiles3 =
[
- {create_dir, "releases",
+ {create_dir, "releases",
[StartFile,
{create_dir,BootVsn, RelFiles}]},
{create_dir, "bin", BinFiles}
@@ -621,14 +676,15 @@ strip_sys_files(Relocatable, SysFiles, Apps, ExclRegexps) ->
ExclRegexps2 =
case Relocatable of
true ->
- ExtraExcl = ["^erts.*/bin/.*src$"],
- reltool_utils:decode_regexps(excl_sys_filters, {add, ExtraExcl}, ExclRegexps);
+ ExtraExcl = ["^erts.*/bin/.*src\$"],
+ reltool_utils:decode_regexps(excl_sys_filters,
+ {add, ExtraExcl}, ExclRegexps);
false ->
ExclRegexps
end,
{value, Erts} = lists:keysearch(erts, #app.name, Apps),
FilterErts =
- fun(Spec) ->
+ fun(Spec) ->
File = element(2, Spec),
case lists:prefix("erts", File) of
true ->
@@ -636,7 +692,7 @@ strip_sys_files(Relocatable, SysFiles, Apps, ExclRegexps) ->
File =:= Erts#app.label ->
replace_dyn_erl(Relocatable, Spec);
true ->
- false
+ false
end;
false ->
true
@@ -660,7 +716,11 @@ replace_dyn_erl(true, {create_dir, ErtsDir, ErtsFiles}) ->
[{copy_file, ErlIni}] ->
%% Remove Windows .ini file
BinFiles2 = lists:keydelete(ErlIni, 2, BinFiles),
- ErtsFiles2 = lists:keyreplace("bin", 2, ErtsFiles, {create_dir, "bin", BinFiles2}),
+ ErtsFiles2 =
+ lists:keyreplace("bin",
+ 2,
+ ErtsFiles,
+ {create_dir, "bin", BinFiles2}),
{true, {create_dir, ErtsDir, ErtsFiles2}}
end;
[{copy_file, DynErlExe}] ->
@@ -668,33 +728,42 @@ replace_dyn_erl(true, {create_dir, ErtsDir, ErtsFiles}) ->
ErlExe = "erl" ++ filename:extension(DynErlExe),
BinFiles2 = lists:keydelete(DynErlExe, 2, BinFiles),
DynErlExe2 = filename:join([ErtsDir, "bin", DynErlExe]),
- BinFiles3 = lists:keyreplace(ErlExe, 2, BinFiles2, {copy_file, ErlExe, DynErlExe2}),
- ErtsFiles2 = lists:keyreplace("bin", 2, ErtsFiles, {create_dir, "bin", BinFiles3}),
+ BinFiles3 = lists:keyreplace(ErlExe,
+ 2,
+ BinFiles2,
+ {copy_file, ErlExe, DynErlExe2}),
+ ErtsFiles2 = lists:keyreplace("bin",
+ 2,
+ ErtsFiles,
+ {create_dir, "bin", BinFiles3}),
{true, {create_dir, ErtsDir, ErtsFiles2}}
end.
spec_bin_files(Sys, AllSysFiles, StrippedSysFiles, RelFiles, InclRegexps) ->
- [{create_dir, ErtsLabel, ErtsFiles}] = safe_lookup_spec("erts", StrippedSysFiles),
+ [{create_dir, ErtsLabel, ErtsFiles}] =
+ safe_lookup_spec("erts", StrippedSysFiles),
[{create_dir, _, BinFiles}] = safe_lookup_spec("bin", ErtsFiles),
ErtsBin = filename:join([ErtsLabel, "bin"]),
Escripts = spec_escripts(Sys, ErtsBin, BinFiles),
Map = fun({copy_file, File}) ->
{copy_file, File, filename:join([ErtsBin, File])};
({copy_file, NewFile, OldFile}) ->
- {_, OldFile2} = abs_to_rel_path(ErtsBin, filename:join([ErtsBin, OldFile])),
+ {_, OldFile2} =
+ abs_to_rel_path(ErtsBin,
+ filename:join([ErtsBin, OldFile])),
{copy_file, NewFile, OldFile2}
end,
%% Do only copy those bin files from erts/bin that also exists in bin
[{create_dir, _, OldBinFiles}] = safe_lookup_spec("bin", AllSysFiles),
GoodNames = [F || {copy_file, F} <- OldBinFiles,
- not lists:suffix(".boot", F),
+ not lists:suffix(".boot", F),
not lists:suffix(".script", F)],
BinFiles2 = [Map(S) || S <- BinFiles, lists:member(element(2, S), GoodNames)],
BootFiles = [F || F <- RelFiles, lists:suffix(".boot", element(2, F))],
[{write_file, _, BootRel}] = safe_lookup_spec(Sys#sys.boot_rel ++ ".boot", BootFiles),
BootFiles2 = lists:keystore("start.boot", 2, BootFiles, {write_file, "start.boot", BootRel}),
- MakeRegexp = fun(File) -> "^bin/" ++ element(2, File) ++ "(|.escript)$" end,
+ MakeRegexp = fun(File) -> "^bin/" ++ element(2, File) ++ "(|.escript)\$" end,
ExtraIncl = lists:map(MakeRegexp, Escripts),
InclRegexps2 = reltool_utils:decode_regexps(incl_sys_filters, {add, ExtraIncl}, InclRegexps),
{InclRegexps2, Escripts ++ BinFiles2 ++ BootFiles2}.
@@ -722,7 +791,7 @@ do_spec_escript(File, ErtsBin, BinFiles) ->
ExeExt = filename:extension(EscriptExe),
[{copy_file, Base ++ EscriptExt, File},
{copy_file, Base ++ ExeExt, filename:join([ErtsBin, EscriptExe])}].
-
+
check_sys(Mandatory, SysFiles) ->
lists:foreach(fun(M) -> do_check_sys(M, SysFiles) end, Mandatory).
@@ -730,7 +799,8 @@ do_check_sys(Prefix, Specs) ->
%%io:format("Prefix: ~p\n", [Prefix]),
case lookup_spec(Prefix, Specs) of
[] ->
- reltool_utils:throw_error("Mandatory system directory ~s is not included",
+ reltool_utils:throw_error("Mandatory system directory ~s "
+ "is not included",
[Prefix]);
_ ->
ok
@@ -750,7 +820,8 @@ lookup_spec(Prefix, Specs) ->
safe_lookup_spec(Prefix, Specs) ->
case lookup_spec(Prefix, Specs) of
[] ->
- reltool_utils:throw_error("Mandatory system file ~s is not included", [Prefix]);
+ reltool_utils:throw_error("Mandatory system file ~s is "
+ "not included", [Prefix]);
Match ->
Match
end.
@@ -780,7 +851,8 @@ spec_lib_files(#sys{apps = Apps} = Sys) ->
check_apps([Mandatory | Names], Apps) ->
case lists:keymember(Mandatory, #app.name, Apps) of
false ->
- reltool_utils:throw_error("Mandatory application ~p is not included in ~p",
+ reltool_utils:throw_error("Mandatory application ~p is "
+ "not included in ~p",
[Mandatory, Apps]);
true ->
check_apps(Names, Apps)
@@ -804,8 +876,12 @@ spec_app(#app{name = Name,
EbinDir = filename:join([SourceDir, "ebin"]),
OptAppUpFileSpec = spec_opt_copy_file(EbinDir, AppUpFilename),
OptAppFileSpec = spec_app_file(App, Sys, EbinDir),
- ModSpecs = [spec_mod(M, SysDebugInfo) || M <- Mods, M#mod.is_included, M#mod.exists],
- NewEbin = {create_dir, "ebin", OptAppUpFileSpec ++ OptAppFileSpec ++ ModSpecs},
+ ModSpecs = [spec_mod(M, SysDebugInfo) || M <- Mods,
+ M#mod.is_included,
+ M#mod.exists],
+ NewEbin = {create_dir,
+ "ebin",
+ OptAppUpFileSpec ++ OptAppFileSpec ++ ModSpecs},
AppFiles2 = lists:keystore("ebin", 2, AppFiles, NewEbin),
%% Apply file filter
@@ -826,24 +902,32 @@ spec_archive(#app{label = Label,
excl_archive_filters = SysExclArchiveDirs,
archive_opts = SysArchiveOpts},
Files) ->
- InclArchiveDirs = reltool_utils:default_val(AppInclArchiveDirs, SysInclArchiveDirs),
- ExclArchiveDirs = reltool_utils:default_val(AppExclArchiveDirs, SysExclArchiveDirs),
- ArchiveOpts = reltool_utils:default_val(AppArchiveOpts, SysArchiveOpts),
+ InclArchiveDirs =
+ reltool_utils:default_val(AppInclArchiveDirs, SysInclArchiveDirs),
+ ExclArchiveDirs =
+ reltool_utils:default_val(AppExclArchiveDirs, SysExclArchiveDirs),
+ ArchiveOpts =
+ reltool_utils:default_val(AppArchiveOpts, SysArchiveOpts),
Match = fun(F) -> match(element(2, F), InclArchiveDirs, ExclArchiveDirs) end,
case lists:filter(Match, Files) of
[] ->
%% Nothing to archive
[spec_create_dir(RootDir, SourceDir, Label, Files)];
ArchiveFiles ->
- OptDir =
+ OptDir =
case Files -- ArchiveFiles of
[] ->
[];
ExternalFiles ->
- [spec_create_dir(RootDir, SourceDir, Label, ExternalFiles)]
+ [spec_create_dir(RootDir,
+ SourceDir,
+ Label,
+ ExternalFiles)]
end,
- ArchiveOpts = reltool_utils:default_val(AppArchiveOpts, SysArchiveOpts),
- ArchiveDir = spec_create_dir(RootDir, SourceDir, Label, ArchiveFiles),
+ ArchiveOpts =
+ reltool_utils:default_val(AppArchiveOpts, SysArchiveOpts),
+ ArchiveDir =
+ spec_create_dir(RootDir, SourceDir, Label, ArchiveFiles),
[{archive, Label ++ ".ez", ArchiveOpts, [ArchiveDir]} | OptDir]
end.
@@ -854,7 +938,9 @@ spec_dir(Dir) ->
case erl_prim_loader:list_dir(Dir) of
{ok, Files} ->
%% Directory
- {create_dir, Base, [spec_dir(filename:join([Dir, F])) || F <- Files]};
+ {create_dir,
+ Base,
+ [spec_dir(filename:join([Dir, F])) || F <- Files]};
error ->
reltool_utils:throw_error("list dir ~s failed\n", [Dir])
end;
@@ -895,7 +981,7 @@ spec_app_file(#app{name = Name,
App2 = App#app{info = Info#app_info{modules = ModNames}},
Contents = gen_app(App2),
AppIoList = io_lib:format("%% app generated at ~w ~w\n~p.\n\n",
- [date(), time(), Contents]),
+ [date(), time(), Contents]),
[{write_file, AppFilename, AppIoList}];
all ->
%% Include all included modules
@@ -904,13 +990,14 @@ spec_app_file(#app{name = Name,
App2 = App#app{info = Info#app_info{modules = ModNames}},
Contents = gen_app(App2),
AppIoList = io_lib:format("%% app generated at ~w ~w\n~p.\n\n",
- [date(), time(), Contents]),
+ [date(), time(), Contents]),
[{write_file, AppFilename, AppIoList}]
-
+
end.
spec_opt_copy_file(DirName, BaseName) ->
- case filelib:is_regular(filename:join([DirName, BaseName]), erl_prim_loader) of
+ case filelib:is_regular(filename:join([DirName, BaseName]),
+ erl_prim_loader) of
true -> [{copy_file, BaseName}];
false -> []
end.
@@ -949,14 +1036,17 @@ eval_spec(Spec, SourceDir, TargetDir) ->
false ->
{error, TargetDir2 ++ ": " ++ file:format_error(enoent)}
end
- catch
+ catch
throw:{error, Text} ->
cleanup_spec(Spec, TargetDir2),
{error, Text}
end.
do_eval_spec(List, OrigSourceDir, SourceDir, TargetDir) when is_list(List) ->
- lists:foreach(fun(F) -> do_eval_spec(F, OrigSourceDir, SourceDir, TargetDir) end, List);
+ lists:foreach(fun(F) ->
+ do_eval_spec(F, OrigSourceDir, SourceDir, TargetDir)
+ end,
+ List);
%% do_eval_spec({source_dir, SourceDir2, Spec}, OrigSourceDir, _SourceDir, TargetDir) ->
%% %% Source dir is absolute or relative the original source dir
%% SourceDir3 = filename:join([OrigSourceDir, SourceDir2]),
@@ -966,12 +1056,18 @@ do_eval_spec({create_dir, Dir, Files}, OrigSourceDir, SourceDir, TargetDir) ->
TargetDir2 = filename:join([TargetDir, Dir]),
reltool_utils:create_dir(TargetDir2),
do_eval_spec(Files, OrigSourceDir, SourceDir2, TargetDir2);
-do_eval_spec({create_dir, Dir, OldDir, Files}, OrigSourceDir, _SourceDir, TargetDir) ->
+do_eval_spec({create_dir, Dir, OldDir, Files},
+ OrigSourceDir,
+ _SourceDir,
+ TargetDir) ->
SourceDir2 = filename:join([OrigSourceDir, OldDir]),
TargetDir2 = filename:join([TargetDir, Dir]),
reltool_utils:create_dir(TargetDir2),
do_eval_spec(Files, SourceDir2, SourceDir2, TargetDir2);
-do_eval_spec({archive, Archive, Options, Files}, OrigSourceDir, SourceDir, TargetDir) ->
+do_eval_spec({archive, Archive, Options, Files},
+ OrigSourceDir,
+ SourceDir,
+ TargetDir) ->
TmpSpec = {create_dir, "tmp", Files},
TmpDir = filename:join([TargetDir, "tmp"]),
reltool_utils:create_dir(TmpDir),
@@ -986,17 +1082,24 @@ do_eval_spec({archive, Archive, Options, Files}, OrigSourceDir, SourceDir, Targe
{ok, _} ->
ok;
{error, Reason} ->
- reltool_utils:throw_error("create archive ~s: ~p\n", [ArchiveFile, Reason])
+ reltool_utils:throw_error("create archive ~s: ~p\n",
+ [ArchiveFile, Reason])
end;
do_eval_spec({copy_file, File}, _OrigSourceDir, SourceDir, TargetDir) ->
SourceFile = filename:join([SourceDir, File]),
TargetFile = filename:join([TargetDir, File]),
reltool_utils:copy_file(SourceFile, TargetFile);
-do_eval_spec({copy_file, File, OldFile}, OrigSourceDir, _SourceDir, TargetDir) ->
+do_eval_spec({copy_file, File, OldFile},
+ OrigSourceDir,
+ _SourceDir,
+ TargetDir) ->
SourceFile = filename:join([OrigSourceDir, OldFile]),
TargetFile = filename:join([TargetDir, File]),
reltool_utils:copy_file(SourceFile, TargetFile);
-do_eval_spec({write_file, File, IoList}, _OrigSourceDir, _SourceDir, TargetDir) ->
+do_eval_spec({write_file, File, IoList},
+ _OrigSourceDir,
+ _SourceDir,
+ TargetDir) ->
TargetFile = filename:join([TargetDir, File]),
reltool_utils:write_file(TargetFile, IoList);
do_eval_spec({strip_beam, File}, _OrigSourceDir, SourceDir, TargetDir) ->
@@ -1039,9 +1142,12 @@ cleanup_spec({strip_beam, File}, TargetDir) ->
filter_spec(List, InclRegexps, ExclRegexps) ->
do_filter_spec("", List, InclRegexps, ExclRegexps).
-
+
do_filter_spec(Path, List, InclRegexps, ExclRegexps) when is_list(List) ->
- lists:zf(fun(File) -> do_filter_spec(Path, File, InclRegexps, ExclRegexps) end, List);
+ lists:zf(fun(File) ->
+ do_filter_spec(Path, File, InclRegexps, ExclRegexps)
+ end,
+ List);
%% do_filter_spec(Path, {source_dir, _SourceDir, Spec}, InclRegexps, ExclRegexps) ->
%% do_filter_spec(Path, Spec, InclRegexps, ExclRegexps);
do_filter_spec(Path, {create_dir, Dir, Files}, InclRegexps, ExclRegexps) ->
@@ -1057,7 +1163,10 @@ do_filter_spec(Path, {create_dir, Dir, Files}, InclRegexps, ExclRegexps) ->
Files2 when is_list(Files2) ->
{true, {create_dir, Dir, Files2}}
end;
-do_filter_spec(Path, {create_dir, NewDir, OldDir, Files}, InclRegexps, ExclRegexps) ->
+do_filter_spec(Path,
+ {create_dir, NewDir, OldDir, Files},
+ InclRegexps,
+ ExclRegexps) ->
Path2 = opt_join(Path, NewDir),
case do_filter_spec(Path2, Files, InclRegexps, ExclRegexps) of
[] ->
@@ -1070,7 +1179,10 @@ do_filter_spec(Path, {create_dir, NewDir, OldDir, Files}, InclRegexps, ExclRegex
Files2 when is_list(Files2) ->
{true, {create_dir, NewDir, OldDir, Files2}}
end;
-do_filter_spec(Path, {archive, Archive, Options, Files}, InclRegexps, ExclRegexps) ->
+do_filter_spec(Path,
+ {archive, Archive, Options, Files},
+ InclRegexps,
+ ExclRegexps) ->
case do_filter_spec(Path, Files, InclRegexps, ExclRegexps) of
[] ->
case match(Path, InclRegexps, ExclRegexps) of
@@ -1085,7 +1197,10 @@ do_filter_spec(Path, {archive, Archive, Options, Files}, InclRegexps, ExclRegexp
do_filter_spec(Path, {copy_file, File}, InclRegexps, ExclRegexps) ->
Path2 = opt_join(Path, File),
match(Path2, InclRegexps, ExclRegexps);
-do_filter_spec(Path, {copy_file, NewFile, _OldFile}, InclRegexps, ExclRegexps) ->
+do_filter_spec(Path,
+ {copy_file, NewFile, _OldFile},
+ InclRegexps,
+ ExclRegexps) ->
Path2 = opt_join(Path, NewFile),
match(Path2, InclRegexps, ExclRegexps);
do_filter_spec(Path, {write_file, File, _IoList}, InclRegexps, ExclRegexps) ->
@@ -1101,7 +1216,7 @@ opt_join(Path, File) ->
filename:join([Path, File]).
match(String, InclRegexps, ExclRegexps) ->
- %%case
+ %%case
match(String, InclRegexps) andalso not match(String, ExclRegexps).
%% of
%% true ->
@@ -1109,7 +1224,7 @@ match(String, InclRegexps, ExclRegexps) ->
%% false ->
%% io:format("no match: ~p\n"
%% " incl: ~p\n"
-%% " excl: ~p\n",
+%% " excl: ~p\n",
%% [String, InclRegexps, ExclRegexps]),
%% false
%% end.
@@ -1131,7 +1246,7 @@ match(String, [#regexp{source = _, compiled = MP} | Regexps]) ->
install(RelName, TargetDir) ->
try
do_install(RelName, TargetDir)
- catch
+ catch
throw:{error, Text} ->
{error, Text}
end.
@@ -1148,7 +1263,8 @@ do_install(RelName, TargetDir) ->
case os:type() of
{win32, _} ->
NativeRootDir = filename:nativename(TargetDir2),
- %% NativeBinDir = filename:nativename(filename:join([BinDir, "win32"])),
+ %% NativeBinDir =
+ %% filename:nativename(filename:join([BinDir, "win32"])),
NativeBinDir = filename:nativename(BinDir),
IniData = ["[erlang]\r\n",
"Bindir=", NativeBinDir, "\r\n",
@@ -1157,8 +1273,11 @@ do_install(RelName, TargetDir) ->
IniFile = filename:join([BinDir, "erl.ini"]),
ok = file:write_file(IniFile, IniData);
_ ->
- subst_src_scripts(start_scripts(), ErtsBinDir, BinDir,
- [{"FINAL_ROOTDIR", TargetDir2}, {"EMU", "beam"}],
+ subst_src_scripts(start_scripts(),
+ ErtsBinDir,
+ BinDir,
+ [{"FINAL_ROOTDIR", TargetDir2},
+ {"EMU", "beam"}],
[preserve])
end,
RelFile = filename:join([RelDir, RelVsn, RelName ++ ".rel"]),
@@ -1169,13 +1288,15 @@ do_install(RelName, TargetDir) ->
end.
subst_src_scripts(Scripts, SrcDir, DestDir, Vars, Opts) ->
- Fun = fun(Script) -> subst_src_script(Script, SrcDir, DestDir, Vars, Opts) end,
+ Fun = fun(Script) ->
+ subst_src_script(Script, SrcDir, DestDir, Vars, Opts)
+ end,
lists:foreach(Fun, Scripts).
-subst_src_script(Script, SrcDir, DestDir, Vars, Opts) ->
+subst_src_script(Script, SrcDir, DestDir, Vars, Opts) ->
subst_file(filename:join([SrcDir, Script ++ ".src"]),
filename:join([DestDir, Script]),
- Vars,
+ Vars,
Opts).
subst_file(Src, Dest, Vars, Opts) ->
diff --git a/lib/reltool/src/reltool_utils.erl b/lib/reltool/src/reltool_utils.erl
index 8d52ade9be..403fa574c5 100644
--- a/lib/reltool/src/reltool_utils.erl
+++ b/lib/reltool/src/reltool_utils.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
-module(reltool_utils).
@@ -30,11 +30,11 @@ root_dir() ->
erl_libs() ->
case os:getenv("ERL_LIBS") of
- false ->
+ false ->
[];
LibStr ->
string:tokens(LibStr, ":;")
- end.
+ end.
lib_dirs(Dir) ->
case erl_prim_loader:list_dir(Dir) of
@@ -42,7 +42,7 @@ lib_dirs(Dir) ->
[F || F <- Files,
filelib:is_dir(filename:join([Dir, F]),
erl_prim_loader)];
- error ->
+ error ->
[]
end.
@@ -55,7 +55,7 @@ split_app_name(Name) ->
Elem >= $0, Elem =< $9 -> true;
true -> false
end
- end,
+ end,
case lists:splitwith(Pred, lists:reverse(Name)) of
{Vsn, [$- | App]} ->
{list_to_atom(lists:reverse(App)), lists:reverse(Vsn)};
@@ -119,7 +119,7 @@ default_rels() ->
assign_image_list(ListCtrl) ->
Art = wxImageList:new(16,16),
- [wxImageList:add(Art, wxArtProvider:getBitmap(Image, [{size, {16,16}}]))
+ [wxImageList:add(Art, wxArtProvider:getBitmap(Image, [{size, {16,16}}]))
|| Image <- ["wxART_ERROR",
"wxART_WARNING",
"wxART_QUESTION",
@@ -206,7 +206,7 @@ split_app_dir(Dir) ->
ParentDir = filename:dirname(Dir),
Base = filename:basename(Dir),
{Name, Vsn} = split_app_name(Base),
- Vsn2 =
+ Vsn2 =
try
[list_to_integer(N) || N <- string:tokens(Vsn, ".")]
catch
@@ -276,7 +276,9 @@ get_selected_items(ListCtrl, PrevItem, Acc) ->
ItemNo ->
case wxListCtrl:getItemText(ListCtrl, ItemNo) of
Text when Text =/= ?MISSING_APP_TEXT ->
- get_selected_items(ListCtrl, ItemNo, [{ItemNo, Text} | Acc]);
+ get_selected_items(ListCtrl,
+ ItemNo,
+ [{ItemNo, Text} | Acc]);
_Text ->
get_selected_items(ListCtrl, ItemNo, Acc)
end
@@ -306,7 +308,8 @@ select_items(ListCtrl, OldItems, NewItems) ->
select_item(ListCtrl, NewItems);
ValidItems ->
%% Some old selections are still valid. Select them again.
- lists:foreach(fun(Item) -> select_item(ListCtrl, [Item]) end, ValidItems)
+ lists:foreach(fun(Item) -> select_item(ListCtrl, [Item]) end,
+ ValidItems)
end.
select_item(ListCtrl, [{ItemNo, Text} | Items]) ->
@@ -339,7 +342,7 @@ print(_, _, _, _) ->
ok.
%% -define(SAFE(M,F,A), safe(M, F, A, ?MODULE, ?LINE)).
-%%
+%%
%% safe(M, F, A, Mod, Line) ->
%% case catch apply(M, F, A) of
%% {'EXIT', Reason} ->
@@ -356,7 +359,7 @@ return_first_error(Status, NewError) when is_list(NewError) ->
{error, OldError} ->
{error, OldError}
end.
-
+
add_warning(Status, Warning) ->
case Status of
{ok, Warnings} ->
@@ -429,7 +432,8 @@ recursive_delete(Dir) ->
true ->
case file:list_dir(Dir) of
{ok, Files} ->
- Fun = fun(F) -> recursive_delete(filename:join([Dir, F])) end,
+ Fun =
+ fun(F) -> recursive_delete(filename:join([Dir, F])) end,
lists:foreach(Fun, Files),
delete(Dir, directory);
{error, enoent} ->
@@ -514,7 +518,9 @@ decode_regexps(Key, Regexps, _Old) when is_list(Regexps) ->
do_decode_regexps(Key, [Regexp | Regexps], Acc) ->
case catch re:compile(Regexp, []) of
{ok, MP} ->
- do_decode_regexps(Key, Regexps, [#regexp{source = Regexp, compiled = MP} | Acc]);
+ do_decode_regexps(Key,
+ Regexps,
+ [#regexp{source = Regexp, compiled = MP} | Acc]);
_ ->
Text = lists:flatten(io_lib:format("~p", [{Key, Regexp}])),
throw({error, "Illegal option: " ++ Text})
@@ -532,6 +538,27 @@ default_val(Val, Default) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+escript_foldl(Fun, Acc, File) ->
+ case escript:extract(File, [compile_source]) of
+ {ok, [_Shebang, _Comment, _EmuArgs, Body]} ->
+ case Body of
+ {source, BeamCode} ->
+ GetInfo = fun() -> file:read_file_info(File) end,
+ GetBin = fun() -> BeamCode end,
+ {ok, Fun(".", GetInfo, GetBin, Acc)};
+ {beam, BeamCode} ->
+ GetInfo = fun() -> file:read_file_info(File) end,
+ GetBin = fun() -> BeamCode end,
+ {ok, Fun(".", GetInfo, GetBin, Acc)};
+ {archive, ArchiveBin} ->
+ zip:foldl(Fun, Acc, {File, ArchiveBin})
+ end;
+ {error, Reason} ->
+ {error, Reason}
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
call(Name, Msg) when is_atom(Name) ->
call(whereis(Name), Msg);
call(Pid, Msg) when is_pid(Pid) ->
diff --git a/lib/runtime_tools/doc/src/erts_alloc_config.xml b/lib/runtime_tools/doc/src/erts_alloc_config.xml
index 5e7cbe4172..6acf498411 100644
--- a/lib/runtime_tools/doc/src/erts_alloc_config.xml
+++ b/lib/runtime_tools/doc/src/erts_alloc_config.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2007</year><year>2009</year>
+ <year>2007</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>erts_alloc_config</title>
@@ -68,7 +68,7 @@
command-line flag to the Erlang runtime system you are going
to use for creation of the allocator configuration. It will
disable features that prevent <c>erts_alloc_config</c> from
- doing it's job. Note, you should <em>not</em> use this flag
+ doing its job. Note, you should <em>not</em> use this flag
when using the created configuration. Also note that it is
important that you use the same
<seealso marker="erts:erl#+S">amount of schedulers</seealso>
diff --git a/lib/runtime_tools/src/dbg.erl b/lib/runtime_tools/src/dbg.erl
index 66ac0422eb..56283f4d3d 100644
--- a/lib/runtime_tools/src/dbg.erl
+++ b/lib/runtime_tools/src/dbg.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
-module(dbg).
@@ -945,7 +945,7 @@ dhandler(end_of_trace, Out) ->
dhandler(Trace, Out) when element(1, Trace) == trace, tuple_size(Trace) >= 3 ->
dhandler1(Trace, tuple_size(Trace), Out);
dhandler(Trace, Out) when element(1, Trace) == trace_ts, tuple_size(Trace) >= 4 ->
- dhandler1(Trace, tuple_size(Trace)-1, Out);
+ dhandler1(Trace, tuple_size(Trace)-1, element(tuple_size(Trace),Trace), Out);
dhandler(Trace, Out) when element(1, Trace) == drop, tuple_size(Trace) =:= 2 ->
io:format(Out, "*** Dropped ~p messages.~n", [element(2,Trace)]),
Out;
@@ -978,24 +978,18 @@ dhandler(_Trace, Out) ->
Out.
dhandler1(Trace, Size, Out) ->
-%%%! Self = self(),
From = element(2, Trace),
case element(3, Trace) of
'receive' ->
case element(4, Trace) of
{dbg,ok} -> ok;
- Message -> io:format(Out, "(~p) << ~p~n", [From,Message])
+ Message ->
+ io:format(Out, "(~p) << ~p~n", [From,Message])
end;
'send' ->
Message = element(4, Trace),
- case element(5, Trace) of
-%%%! This causes messages to disappear when used by ttb (observer). Tests
-%%%! so far show that there is no difference in results with dbg even if I
-%%%! comment it out, so I hope this is only some old code which isn't
-%%%! needed anymore... /siri
-%%%! Self -> ok;
- To -> io:format(Out, "(~p) ~p ! ~p~n", [From,To,Message])
- end;
+ To = element(5, Trace),
+ io:format(Out, "(~p) ~p ! ~p~n", [From,To,Message]);
call ->
case element(4, Trace) of
MFA when Size == 5 ->
@@ -1028,6 +1022,51 @@ dhandler1(Trace, Size, Out) ->
end,
Out.
+dhandler1(Trace, Size, TS, Out) ->
+ From = element(2, Trace),
+ case element(3, Trace) of
+ 'receive' ->
+ case element(4, Trace) of
+ {dbg,ok} -> ok;
+ Message ->
+ io:format(Out, "(~p) << ~p (Timestamp: ~p)~n", [From,Message,TS])
+ end;
+ 'send' ->
+ Message = element(4, Trace),
+ To = element(5, Trace),
+ io:format(Out, "(~p) ~p ! ~p (Timestamp: ~p)~n", [From,To,Message,TS]);
+ call ->
+ case element(4, Trace) of
+ MFA when Size == 5 ->
+ Message = element(5, Trace),
+ io:format(Out, "(~p) call ~s (~p) (Timestamp: ~p)~n", [From,ffunc(MFA),Message,TS]);
+ MFA ->
+ io:format(Out, "(~p) call ~s (Timestamp: ~p)~n", [From,ffunc(MFA),TS])
+ end;
+ return -> %% To be deleted...
+ case element(4, Trace) of
+ MFA when Size == 5 ->
+ Ret = element(5, Trace),
+ io:format(Out, "(~p) old_ret ~s -> ~p (Timestamp: ~p)~n", [From,ffunc(MFA),Ret,TS]);
+ MFA ->
+ io:format(Out, "(~p) old_ret ~s (Timestamp: ~p)~n", [From,ffunc(MFA),TS])
+ end;
+ return_from ->
+ MFA = element(4, Trace),
+ Ret = element(5, Trace),
+ io:format(Out, "(~p) returned from ~s -> ~p (Timestamp: ~p)~n", [From,ffunc(MFA),Ret,TS]);
+ return_to ->
+ MFA = element(4, Trace),
+ io:format(Out, "(~p) returning to ~s (Timestamp: ~p)~n", [From,ffunc(MFA),TS]);
+ spawn when Size == 5 ->
+ Pid = element(4, Trace),
+ MFA = element(5, Trace),
+ io:format(Out, "(~p) spawn ~p as ~s (Timestamp: ~p)~n", [From,Pid,ffunc(MFA),TS]);
+ Op ->
+ io:format(Out, "(~p) ~p ~s (Timestamp: ~p)~n", [From,Op,ftup(Trace,4,Size),TS])
+ end,
+ Out.
+
%%% These f* functions returns non-flat strings
diff --git a/lib/snmp/doc/src/notes_history.xml b/lib/snmp/doc/src/notes_history.xml
index 8739400773..934df87866 100644
--- a/lib/snmp/doc/src/notes_history.xml
+++ b/lib/snmp/doc/src/notes_history.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2004</year><year>2009</year>
+ <year>2004</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>SNMP Release Notes history</title>
@@ -1732,7 +1732,7 @@
version 4.1. </p>
<p>When performing a downgrade, make sure the verbosity of the
manager server process is silence, or else the process will crash
- (due to a bug in version 4.0.4) and be restarted by it's
+ (due to a bug in version 4.0.4) and be restarted by its
supervisor.</p>
<section>
@@ -1773,7 +1773,7 @@
version 4.0.4. </p>
<p>When performing a downgrade, make sure the verbosity of the
manager server process is silence, or else the process will crash
- (due to a bug in version 4.0.4) and be restarted by it's
+ (due to a bug in version 4.0.4) and be restarted by its
supervisor.</p>
<section>
@@ -1827,8 +1827,8 @@
</item>
<item>
<p>[manager] The server process contained a bug that caused it
- to crash, if it received an exit message from it's gct (GC timer)
- process and it's verbosity was <em>log</em> or higher. </p>
+ to crash, if it received an exit message from its gct (GC timer)
+ process and its verbosity was <em>log</em> or higher. </p>
<p>This also effects the application downgrade. </p>
<p>Own Id: OTP-5306</p>
</item>
diff --git a/lib/snmp/doc/src/snmp_app.xml b/lib/snmp/doc/src/snmp_app.xml
index e5a725d720..57eb87a759 100644
--- a/lib/snmp/doc/src/snmp_app.xml
+++ b/lib/snmp/doc/src/snmp_app.xml
@@ -80,7 +80,7 @@
<!-- The info below is also found in the snmp_config.xml file -->
- <p>Each snmp component has it's own set of configuration parameters,
+ <p>Each snmp component has its own set of configuration parameters,
even though some of the types are common to both components. </p>
<pre>
@@ -693,7 +693,7 @@
<p>Specifies if and how the audit trail log shall be repaired
when opened. Unless this parameter has the value <c>snmp_repair</c>
it is sent to <c>disk_log</c>. If, on the other hand, the value is
- <c>snmp_repair</c>, snmp attempts to handle certain faults on it's
+ <c>snmp_repair</c>, snmp attempts to handle certain faults on its
own. And even if it cannot repair the file, it does not truncate it
directly, but instead <em>moves it aside</em> for later off-line
analysis.</p>
diff --git a/lib/snmp/doc/src/snmp_config.xml b/lib/snmp/doc/src/snmp_config.xml
index 6fc9cc49f2..5bd36305fc 100644
--- a/lib/snmp/doc/src/snmp_config.xml
+++ b/lib/snmp/doc/src/snmp_config.xml
@@ -704,7 +704,7 @@
<p>Specifies if and how the audit trail log shall be repaired
when opened. Unless this parameter has the value <c>snmp_repair</c>
it is sent to <c>disk_log</c>. If, on the other hand, the value is
- <c>snmp_repair</c>, snmp attempts to handle certain faults on it's
+ <c>snmp_repair</c>, snmp attempts to handle certain faults on its
own. And even if it cannot repair the file, it does not truncate it
directly, but instead <em>moves it aside</em> for later off-line
analysis.</p>
diff --git a/lib/snmp/doc/src/snmpa_network_interface_filter.xml b/lib/snmp/doc/src/snmpa_network_interface_filter.xml
index d625fd3e4a..10419517dd 100644
--- a/lib/snmp/doc/src/snmpa_network_interface_filter.xml
+++ b/lib/snmp/doc/src/snmpa_network_interface_filter.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2007</year><year>2009</year>
+ <year>2007</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>snmpa_network_interface_filter</title>
@@ -153,7 +153,7 @@ pdu_type() = 'get-request' | 'get-next-request' | 'get-response' | 'set-request'
<p>For the message to be discarded all together, the function
<em>must</em> return <em>false</em>. </p>
<p>Note that it is possible for this function to filter out targets
- (but <em>not</em> add it's own) by returning an updated
+ (but <em>not</em> add its own) by returning an updated
<c>Targets</c> list (<c>NewTargets</c>). </p>
</desc>
</func>
diff --git a/lib/snmp/doc/src/snmpm.xml b/lib/snmp/doc/src/snmpm.xml
index 9e7ac75daf..1ee391d9ba 100644
--- a/lib/snmp/doc/src/snmpm.xml
+++ b/lib/snmp/doc/src/snmpm.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2004</year><year>2009</year>
+ <year>2004</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>snmpm</title>
@@ -920,7 +920,7 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1
<v>Oids = [oid()]</v>
</type>
<desc>
- <p>Transform a alias-name to it's oid.</p>
+ <p>Transform a alias-name to its oid.</p>
<p>Note that an alias-name is only unique within the mib, so
when loading several mib's into a manager, there might be
several instances of the same aliasname.</p>
@@ -938,7 +938,7 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1
<v>Reason = term()</v>
</type>
<desc>
- <p>Transform a oid to it's aliasname.</p>
+ <p>Transform a oid to its aliasname.</p>
<marker id="oid_to_type"></marker>
</desc>
diff --git a/lib/ssh/doc/src/notes.xml b/lib/ssh/doc/src/notes.xml
index 9597137cdf..2533ab8085 100644
--- a/lib/ssh/doc/src/notes.xml
+++ b/lib/ssh/doc/src/notes.xml
@@ -29,6 +29,30 @@
<file>notes.xml</file>
</header>
+ <section><title>Ssh 1.1.9</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>The configuration parameter ip_v6_disabled is now available,
+ which makes it possible for the user to alter the IP version
+ SSH shall use.</p>
+ <p>Own Id: OTP-8535 Aux Id:</p>
+ </item>
+ <item>
+ <p>The ssh_connection:send operation now accepts infinity as timeout.</p>
+ <p>Own Id: OTP-8534 Aux Id:</p>
+ </item>
+ <item>
+ <p>The connection handler now include stack traces when a channel
+ message is not handled correctly.</p>
+ <p>Own Id: OTP-8524 Aux Id:</p>
+ </item>
+ </list>
+ </section>
+
+ </section>
+
<section><title>Ssh 1.1.8</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/ssh/doc/src/ssh.xml b/lib/ssh/doc/src/ssh.xml
index aca5c9cdc4..71e6b2cd3d 100644
--- a/lib/ssh/doc/src/ssh.xml
+++ b/lib/ssh/doc/src/ssh.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2004</year><year>2009</year>
+ <year>2004</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>ssh</title>
@@ -159,6 +159,9 @@
<item>
<p>Allow an existing file-descriptor to be used
(simply passed on to the transport protocol).</p></item>
+ <tag><c><![CDATA[{ip_v6_disabled, boolean()}]]></c></tag>
+ <item>
+ <p>Determines if SSH shall use IPv6 or not.</p></item>
</taglist>
</desc>
</func>
@@ -198,8 +201,8 @@
<item>
Provides specifications for handling of subsystems. The
"sftp" subsystem-spec can be retrieved by calling
- ssh_sftd:subsystem_spec/1. If the subsystems option in not present
- the value of <c>[ssh_sftd:subsystem_spec([])]</c> will be used.
+ ssh_sftpd:subsystem_spec/1. If the subsystems option in not present
+ the value of <c>[ssh_sftpd:subsystem_spec([])]</c> will be used.
It is of course possible to set the option to the empty list
if you do not want the daemon to run any subsystems at all.
</item>
@@ -252,6 +255,10 @@
<item>
<p>Allow an existing file-descriptor to be used
(simply passed on to the transport protocol).</p></item>
+ <tag><c><![CDATA[{ip_v6_disabled, boolean()}]]></c></tag>
+ <item>
+ <p>Determines if SSH shall use IPv6 or not (only used when
+ HostAddress is set to any).</p></item>
</taglist>
</desc>
</func>
diff --git a/lib/ssh/src/ssh.appup.src b/lib/ssh/src/ssh.appup.src
index 5329373862..b082d66988 100644
--- a/lib/ssh/src/ssh.appup.src
+++ b/lib/ssh/src/ssh.appup.src
@@ -19,7 +19,13 @@
{"%VSN%",
[
- {"1.1.7", [{load_module, ssh_connection_handler, soft_purge, soft_purge, []}]},
+ {"1.1.8", [{load_module, ssh_connection_manager, soft_purge, soft_purge, []},
+ {load_module, ssh, soft_purge, soft_purge, []},
+ {load_module, ssh_connection, soft_purge, soft_purge, []}]},
+ {"1.1.7", [{load_module, ssh_connection_handler, soft_purge, soft_purge, []},
+ {load_module, ssh_connection, soft_purge, soft_purge, []},
+ {load_module, ssh, soft_purge, soft_purge, []},
+ {load_module, ssh_connection_manager, soft_purge, soft_purge, []}]},
{"1.1.6", [{restart_application, ssh}]},
{"1.1.5", [{restart_application, ssh}]},
{"1.1.4", [{restart_application, ssh}]},
@@ -27,7 +33,13 @@
{"1.1.2", [{restart_application, ssh}]}
],
[
- {"1.1.7", [{load_module, ssh_connection_handler, soft_purge, soft_purge, []}]},
+ {"1.1.8", [{load_module, ssh_connection_manager, soft_purge, soft_purge, []},
+ {load_module, ssh, soft_purge, soft_purge, []},
+ {load_module, ssh_connection, soft_purge, soft_purge, []}]},
+ {"1.1.7", [{load_module, ssh_connection_handler, soft_purge, soft_purge, []},
+ {load_module, ssh_connection, soft_purge, soft_purge, []},
+ {load_module, ssh, soft_purge, soft_purge, []},
+ {load_module, ssh_connection_manager, soft_purge, soft_purge, []}]},
{"1.1.6", [{restart_application, ssh}]},
{"1.1.5", [{restart_application, ssh}]},
{"1.1.4", [{restart_application, ssh}]},
diff --git a/lib/ssh/src/ssh.erl b/lib/ssh/src/ssh.erl
index f9a986a8b6..0eef3f95c0 100644
--- a/lib/ssh/src/ssh.erl
+++ b/lib/ssh/src/ssh.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -330,10 +330,10 @@ handle_options([{nodelay, _} = Opt | Rest], SockOpts, Opts) ->
handle_options([Opt | Rest], SockOpts, Opts) ->
handle_options(Rest, SockOpts, [Opt | Opts]).
+%% Has IPv6 been disabled?
inetopt(true) ->
- inet6;
-
+ inet;
inetopt(false) ->
- inet.
+ inet6.
diff --git a/lib/ssh/src/ssh_connection.erl b/lib/ssh/src/ssh_connection.erl
index 0aaf1c18d2..b9827c90ea 100644
--- a/lib/ssh/src/ssh_connection.erl
+++ b/lib/ssh/src/ssh_connection.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -123,6 +123,8 @@ send(ConnectionManager, ChannelId, Data) ->
send(ConnectionManager, ChannelId, 0, Data, infinity).
send(ConnectionManager, ChannelId, Data, TimeOut) when is_integer(TimeOut) ->
send(ConnectionManager, ChannelId, 0, Data, TimeOut);
+send(ConnectionManager, ChannelId, Data, infinity) ->
+ send(ConnectionManager, ChannelId, 0, Data, infinity);
send(ConnectionManager, ChannelId, Type, Data) ->
send(ConnectionManager, ChannelId, Type, Data, infinity).
send(ConnectionManager, ChannelId, Type, Data, TimeOut) ->
diff --git a/lib/ssh/src/ssh_connection_manager.erl b/lib/ssh/src/ssh_connection_manager.erl
index 3863005e74..a2effc177e 100644
--- a/lib/ssh/src/ssh_connection_manager.erl
+++ b/lib/ssh/src/ssh_connection_manager.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%%
@@ -272,18 +272,18 @@ handle_call({ssh_msg, Pid, Msg}, From,
{stop, normal, State#state{connection_state = Connection}}
catch
exit:{noproc, Reason} ->
- Report = io_lib:format("Connection probably terminated:~n~p~n~p~n",
- [ConnectionMsg, Reason]),
+ Report = io_lib:format("Connection probably terminated:~n~p~n~p~n~p~n",
+ [ConnectionMsg, Reason, erlang:get_stacktrace()]),
error_logger:info_report(Report),
{noreply, State};
error:Error ->
- Report = io_lib:format("Connection message returned:~n~p~n~p~n",
- [ConnectionMsg, Error]),
+ Report = io_lib:format("Connection message returned:~n~p~n~p~n~p~n",
+ [ConnectionMsg, Error, erlang:get_stacktrace()]),
error_logger:info_report(Report),
{noreply, State};
exit:Exit ->
- Report = io_lib:format("Connection message returned:~n~p~n~p~n",
- [ConnectionMsg, Exit]),
+ Report = io_lib:format("Connection message returned:~n~p~n~p~n~p~n",
+ [ConnectionMsg, Exit, erlang:get_stacktrace()]),
error_logger:info_report(Report),
{noreply, State}
end;
diff --git a/lib/ssh/vsn.mk b/lib/ssh/vsn.mk
index bc7bceeb24..c275cb7acf 100644
--- a/lib/ssh/vsn.mk
+++ b/lib/ssh/vsn.mk
@@ -1,9 +1,13 @@
#-*-makefile-*- ; force emacs to enter makefile-mode
-SSH_VSN = 1.1.8
+SSH_VSN = 1.1.9
APP_VSN = "ssh-$(SSH_VSN)"
-TICKETS = OTP-8356 \
+TICKETS = OTP-8524 \
+ OTP-8534 \
+ OTP-8535
+
+TICKETS_1.1.8 = OTP-8356 \
OTP-8401
TICKETS_1.1.7 = OTP-8121 \
diff --git a/lib/ssl/doc/src/notes.xml b/lib/ssl/doc/src/notes.xml
index 4265445d23..2dd11bc88e 100644
--- a/lib/ssl/doc/src/notes.xml
+++ b/lib/ssl/doc/src/notes.xml
@@ -31,6 +31,21 @@
<p>This document describes the changes made to the SSL application.
</p>
+<section><title>SSL 3.10.9</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Fixed a crash in the certificate certification part.</p>
+ <p>
+ Own Id: OTP-8510 Aux Id: seq11525 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>SSL 3.10.8</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/ssl/src/ssl.appup.src b/lib/ssl/src/ssl.appup.src
index 3aea2428c9..fdda65021d 100644
--- a/lib/ssl/src/ssl.appup.src
+++ b/lib/ssl/src/ssl.appup.src
@@ -8,7 +8,8 @@
{"3.10.4", [{restart_application, ssl}]},
{"3.10.5", [{restart_application, ssl}]},
{"3.10.6", [{restart_application, ssl}]},
- {"3.10.7", [{restart_application, ssl}]}
+ {"3.10.7", [{restart_application, ssl}]},
+ {"3.10.8", [{restart_application, ssl}]}
],
[
{"3.10", [{restart_application, ssl}]},
@@ -18,6 +19,6 @@
{"3.10.4", [{restart_application, ssl}]},
{"3.10.5", [{restart_application, ssl}]},
{"3.10.6", [{restart_application, ssl}]},
- {"3.10.7", [{restart_application, ssl}]}
+ {"3.10.8", [{restart_application, ssl}]}
]}.
diff --git a/lib/ssl/src/ssl_certificate_db.erl b/lib/ssl/src/ssl_certificate_db.erl
index adae92530a..b8c3c6f6b7 100644
--- a/lib/ssl/src/ssl_certificate_db.erl
+++ b/lib/ssl/src/ssl_certificate_db.erl
@@ -159,6 +159,8 @@ issuer_candidate(no_candidate) ->
case ets:first(Db) of
'$end_of_table' ->
no_more_candidates;
+ {file, _} = Key ->
+ issuer_candidate(Key);
Key ->
[Cert] = lookup(Key, Db),
{Key, Cert}
diff --git a/lib/ssl/vsn.mk b/lib/ssl/vsn.mk
index 7c038e5818..bf67fcd257 100644
--- a/lib/ssl/vsn.mk
+++ b/lib/ssl/vsn.mk
@@ -17,9 +17,10 @@
# %CopyrightEnd%
#
-SSL_VSN = 3.10.8
+SSL_VSN = 3.10.9
+TICKETS = OTP-8510
-TICKETS = OTP-8372 OTP-8441 OTP-8459
+#TICKETS_3.10.8 = OTP-8372 OTP-8441 OTP-8459
#TICKETS_3.10.7 = OTP-8260 OTP-8218 OTP-8250
#TICKETS_3.10.6 = OTP-8275
diff --git a/lib/stdlib/doc/src/io_protocol.xml b/lib/stdlib/doc/src/io_protocol.xml
index 201787f7b5..b52e862a5c 100644
--- a/lib/stdlib/doc/src/io_protocol.xml
+++ b/lib/stdlib/doc/src/io_protocol.xml
@@ -195,7 +195,7 @@ latin1, Module, Function, Args} respectively. </p>
below).</p>
<p>The function will be called with the data the io_server finds on
- it's device, returning {done, Result, RestChars} when enough data is
+ its device, returning {done, Result, RestChars} when enough data is
read (in which case Result is sent to the client and RestChars are
kept in the io_server as a buffer for subsequent input) or {more,
Continuation}, indicating that more characters are needed to
@@ -741,7 +741,7 @@ optimize anything however. It is important though that the returned
data is of the right type depending on the options set, so we convert
the lists to binaries in the correct encoding <em>if possible</em>
before returning. The function supplied in the get_until request may,
-as it's final result return anything, so only functions actually
+as its final result return anything, so only functions actually
returning lists can get them converted to binaries. If the request
contained the encoding tag unicode, the lists can contain all unicode
codepoints and the binaries should be in UTF-8, if the encoding tag
diff --git a/lib/stdlib/doc/src/ms_transform.xml b/lib/stdlib/doc/src/ms_transform.xml
index 9f178b426c..ba9f89685b 100644
--- a/lib/stdlib/doc/src/ms_transform.xml
+++ b/lib/stdlib/doc/src/ms_transform.xml
@@ -4,7 +4,7 @@
<erlref>
<header>
<copyright>
- <year>2002</year><year>2009</year>
+ <year>2002</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>ms_transform</title>
@@ -245,7 +245,7 @@ ets:select(emp_tab, ets:fun2ms(
fun(#emp{empno = [$0 | Rest] }) ->
{[$0|Rest],[$1|Rest]}
end)). </code>
- <p>As a matter of fact, this query hit's the feature of partially bound
+ <p>As a matter of fact, this query hits the feature of partially bound
keys in the table type <c>ordered_set</c>, so that not the whole
table need be searched, only the part of the table containing keys
beginning with <c>0</c> is in fact looked into. </p>
diff --git a/lib/stdlib/doc/src/unicode_usage.xml b/lib/stdlib/doc/src/unicode_usage.xml
index c5bf10b63d..f1b0659ea2 100644
--- a/lib/stdlib/doc/src/unicode_usage.xml
+++ b/lib/stdlib/doc/src/unicode_usage.xml
@@ -143,7 +143,7 @@ en_US.UTF-8</pre>
<pre>
$ echo <input>$LC_CTYPE</input>
en_US.UTF-8</pre>
-<p>The LANG or LC_CTYPE setting should be consistent with what the terminal is capable of, there is no portable way for Erlang to ask the actual terminal about it's UTF-8 capacity, we have to rely on the language and character type settings.</p>
+<p>The LANG or LC_CTYPE setting should be consistent with what the terminal is capable of, there is no portable way for Erlang to ask the actual terminal about its UTF-8 capacity, we have to rely on the language and character type settings.</p>
<p>To investigate what Erlang thinks about the terminal, the <c>io:getopts()</c> call can be used when the shell is started:</p>
<pre>
$ <input>LC_CTYPE=en_US.ISO-8859-1 erl</input>
@@ -185,7 +185,7 @@ Eshell V5.7 (abort with ^G)
<tag><c>file</c>, <c>group</c> and <c>user</c></tag>
<item>
<p>I/O-servers throughout the system are able both to handle Unicode data and has options for converting data upon actual output or input to/from the device. As shown earlier, the <seealso marker="stdlib:shell">shell</seealso> has support for Unicode terminals and the <seealso marker="kernel:file">file</seealso> module allows for translation to and from various Unicode formats on disk.</p>
-<p>The actual reading and writing of files with Unicode data is however not best done with the <c>file</c> module as it's interface is byte oriented. A file opened with a Unicode encoding (like UTF-8), is then best read or written using the <seealso marker="stdlib:io">io</seealso> module.</p>
+<p>The actual reading and writing of files with Unicode data is however not best done with the <c>file</c> module as its interface is byte oriented. A file opened with a Unicode encoding (like UTF-8), is then best read or written using the <seealso marker="stdlib:io">io</seealso> module.</p>
</item>
<tag><c>re</c></tag>
<item>
diff --git a/lib/stdlib/doc/src/zip.xml b/lib/stdlib/doc/src/zip.xml
index af407f1925..4d98a20206 100644
--- a/lib/stdlib/doc/src/zip.xml
+++ b/lib/stdlib/doc/src/zip.xml
@@ -42,16 +42,18 @@
<p>By convention, the name of a zip file should end in "<c>.zip</c>".
To abide to the convention, you'll need to add "<c>.zip</c>" yourself
to the name.</p>
- <p>Zip archives are created with the
- <seealso marker="#zip_2">zip/2</seealso> or the
+ <p>Zip archives are created with the
+ <seealso marker="#zip_2">zip/2</seealso> or the
<seealso marker="#zip_2">zip/3</seealso> function. (They are
also available as <c>create</c>, to resemble the <c>erl_tar</c>
module.)</p>
- <p>To extract files from a zip archive, use the
- <seealso marker="#unzip_1">unzip/1</seealso> or the
+ <p>To extract files from a zip archive, use the
+ <seealso marker="#unzip_1">unzip/1</seealso> or the
<seealso marker="#unzip_2">unzip/2</seealso> function. (They are
also available as <c>extract</c>.)</p>
- <p>To return a list of the files in a zip archive, use the
+ <p>To fold a function over all files in a zip archive, use the
+ <seealso marker="#foldl_3">foldl_3</seealso>.</p>
+ <p>To return a list of the files in a zip archive, use the
<seealso marker="#list_dir_1">list_dir/1</seealso> or the
<seealso marker="#list_dir_2">list_dir/2</seealso> function. (They
are also available as <c>table</c>.)</p>
@@ -132,7 +134,7 @@ zip_file() </code>
<type>
<v>Name = filename()</v>
<v>FileList = [FileSpec]</v>
- <v>FileSpec = filename() | {filename(), binary()}</v>
+ <v>FileSpec = filename() | {filename(), binary()} | {filename(), binary(), #file_info{}}</v>
<v>Options = [Option]</v>
<v>Option = memory | cooked | verbose | {comment, Comment} | {cwd, CWD} | {compress, What} | {uncompress, What}</v>
<v>What = all | [Extension] | {add, [Extension]} | {del, [Extension]}</v>
@@ -212,16 +214,16 @@ zip_file() </code>
<taglist>
<tag><c>all</c></tag>
<item><p> means that all files will be compressed (as long
- as they pass the <c>uncompress</c> condition).</p></item>
+ as they pass the <c>uncompress</c> condition).</p></item>
<tag><c>[Extension]</c></tag>
<item><p>means that only files with exactly these extensions
- will be compressed.</p></item>
+ will be compressed.</p></item>
<tag><c>{add,[Extension]}</c></tag>
<item><p>adds these extensions to the list of compress
- extensions.</p></item>
+ extensions.</p></item>
<tag><c>{del,[Extension]}</c></tag>
<item><p>deletes these extensions from the list of compress
- extensions.</p></item>
+ extensions.</p></item>
</taglist>
</item>
<tag><c>{uncompress, What}</c></tag>
@@ -231,16 +233,16 @@ zip_file() </code>
The following values of <c>What</c> are allowed:</p>
<taglist>
<tag><c>all</c></tag>
- <item><p> means that no files will be compressed.</p></item>
+ <item><p> means that no files will be compressed.</p></item>
<tag><c>[Extension]</c></tag>
<item><p>means that files with these extensions will be
- uncompressed.</p></item>
+ uncompressed.</p></item>
<tag><c>{add,[Extension]}</c></tag>
<item><p>adds these extensions to the list of uncompress
- extensions.</p></item>
+ extensions.</p></item>
<tag><c>{del,[Extension]}</c></tag>
<item><p>deletes these extensions from the list of uncompress
- extensions.</p></item>
+ extensions.</p></item>
</taglist>
</item>
</taglist>
@@ -283,7 +285,7 @@ zip_file() </code>
the <c>unzip/2</c> function will only extract the files
whose names are included in <c>FileList</c>. The full
paths, including the names of all sub directories within
- the zip archive, must be specified.</p>
+ the zip archive, must be specified.</p>
</item>
<tag><c>cooked</c></tag>
<item>
@@ -327,6 +329,64 @@ zip_file() </code>
</desc>
</func>
<func>
+ <name>foldl(Fun, Acc0, Archive) -> {ok, Acc1} | {error, Reason}</name>
+ <fsummary>Fold a function over all files in a zip archive</fsummary>
+ <type>
+ <v>Fun = fun(FileInArchive, GetInfo, GetBin, AccIn) -> AccOut</v>
+ <v>FileInArchive = filename()</v>
+ <v>GetInfo = fun() -> #file_info{}</v>
+ <v>GetBin = fun() -> binary()</v>
+ <v>Acc0 = Acc1 = AccIn = AccOut = term()</v>
+ <v>Archive = filename() | {filename(), binary()}</v>
+ </type>
+ <desc>
+ <p>The <marker id="foldl_3"></marker> <c>foldl/3</c> function
+ calls <c>Fun(FileInArchive, GetInfo, GetBin, AccIn)</c> on
+ successive files in the <c>Archive</c>, starting with <c>AccIn
+ == Acc0</c>. <c>FileInArchive</c> is the name that the file
+ has in the archive. <c>GetInfo</c> is a fun that returns info
+ about the the file. <c>GetBin</c> returns the contents of the
+ file. Both <c>GetInfo</c> and <c>GetBin</c> must be called
+ within the <c>Fun</c>. Their behavior is undefined if they are
+ called outside the context of the <c>Fun</c>. The <c>Fun</c>
+ must return a new accumulator which is passed to the next
+ call. <c>foldl/3</c> returns the final value of the
+ accumulator. <c>Acc0</c> is returned if the archive is
+ empty. It is not necessary to iterate over all files in the
+ archive. The iteration may be ended prematurely in a
+ controlled manner by throwing an exception.</p>
+
+ <p>For example:</p>
+ <pre>
+&gt; <input>Name = "dummy.zip".</input>
+"dummy.zip"
+&gt; <input>{ok, {Name, Bin}} = zip:create(Name, [{"foo", &lt;&lt;"FOO"&gt;&gt;}, {"bar", &lt;&lt;"BAR"&gt;&gt;}], [memory]).</input>
+{ok,{"dummy.zip",
+ &lt;&lt;80,75,3,4,20,0,0,0,0,0,74,152,97,60,171,39,212,26,3,0,
+ 0,0,3,0,0,...&gt;&gt;}}
+&gt; <input>{ok, FileSpec} = zip:foldl(fun(N, I, B, Acc) -> [{N, B(), I()} | Acc] end, [], {Name, Bin}).</input>
+{ok,[{"bar",&lt;&lt;"BAR"&gt;&gt;,
+ {file_info,3,regular,read_write,
+ {{2010,3,1},{19,2,10}},
+ {{2010,3,1},{19,2,10}},
+ {{2010,3,1},{19,2,10}},
+ 54,1,0,0,0,0,0}},
+ {"foo",&lt;&lt;"FOO"&gt;&gt;,
+ {file_info,3,regular,read_write,
+ {{2010,3,1},{19,2,10}},
+ {{2010,3,1},{19,2,10}},
+ {{2010,3,1},{19,2,10}},
+ 54,1,0,0,0,0,0}}]}
+&gt; <input>{ok, {Name, Bin}} = zip:create(Name, lists:reverse(FileSpec), [memory]).</input>
+{ok,{"dummy.zip",
+ &lt;&lt;80,75,3,4,20,0,0,0,0,0,74,152,97,60,171,39,212,26,3,0,
+ 0,0,3,0,0,...&gt;&gt;}}
+&gt; <input>catch zip:foldl(fun("foo", _, B, _) -> throw(B()); (_, _, _, Acc) -> Acc end, [], {Name, Bin}). </input>
+&lt;&lt;"FOO"&gt;&gt;
+</pre>
+ </desc>
+ </func>
+ <func>
<name>list_dir(Archive) -> RetValue</name>
<name>list_dir(Archive, Options)</name>
<name>table(Archive) -> RetValue</name>
diff --git a/lib/stdlib/src/erl_expand_records.erl b/lib/stdlib/src/erl_expand_records.erl
index 6fa77f2c3b..a38b7639d8 100644
--- a/lib/stdlib/src/erl_expand_records.erl
+++ b/lib/stdlib/src/erl_expand_records.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2005-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
%% Purpose : Expand records into tuples.
@@ -191,7 +191,6 @@ guard_test1(Test, St) ->
normalise_test(atom, 1) -> is_atom;
normalise_test(binary, 1) -> is_binary;
-normalise_test(constant, 1) -> is_constant;
normalise_test(float, 1) -> is_float;
normalise_test(function, 1) -> is_function;
normalise_test(integer, 1) -> is_integer;
@@ -346,9 +345,6 @@ expr({'fun',Line,{clauses,Cs0}}, St0) ->
{{'fun',Line,{clauses,Cs}},St1};
expr({call,Line,{atom,_,is_record},[A,{atom,_,Name}]}, St) ->
record_test(Line, A, Name, St);
-expr({'cond',Line,Cs0}, St0) ->
- {Cs,St1} = clauses(Cs0, St0),
- {{'cond',Line,Cs},St1};
expr({call,Line,{remote,_,{atom,_,erlang},{atom,_,is_record}},
[A,{atom,_,Name}]}, St) ->
record_test(Line, A, Name, St);
diff --git a/lib/stdlib/src/erl_lint.erl b/lib/stdlib/src/erl_lint.erl
index 22f435aff8..94ad560549 100644
--- a/lib/stdlib/src/erl_lint.erl
+++ b/lib/stdlib/src/erl_lint.erl
@@ -1940,8 +1940,6 @@ expr({'case',Line,E,Cs}, Vt, St0) ->
{Evt,St1} = expr(E, Vt, St0),
{Cvt,St2} = icrt_clauses(Cs, {'case',Line}, vtupdate(Evt, Vt), St1),
{vtmerge(Evt, Cvt),St2};
-expr({'cond',Line,Cs}, Vt, St) ->
- cond_clauses(Cs,{'cond',Line}, Vt, St);
expr({'receive',Line,Cs}, Vt, St) ->
icrt_clauses(Cs, {'receive',Line}, Vt, St);
expr({'receive',Line,Cs,To,ToEs}, Vt, St0) ->
@@ -2717,45 +2715,6 @@ icrt_clause({clause,_Line,H,G,B}, Vt0, St0) ->
{Bvt,St3} = exprs(B, Vt2, St2),
{vtupdate(Bvt, Vt2),St3}.
-%% The tests of 'cond' clauses are normal expressions - not guards.
-%% Variables bound in a test is visible both in the corresponding body
-%% and in the tests and bodies of subsequent clauses: a 'cond' is
-%% *equivalent* to nested case-switches on boolean expressions.
-
-cond_clauses([C], In, Vt, St) ->
- last_cond_clause(C, In, Vt, St);
-cond_clauses([C | Cs], In, Vt, St) ->
- cond_clause(C, Cs, In, Vt, St).
-
-%% see expr/3 for 'case'
-cond_clause({clause,_L,[],[[E]],B}, Cs, In, Vt, St0) ->
- {Evt,St1} = expr(E, Vt, St0),
- {Cvt, St2} = cond_cases(B, Cs, In, vtupdate(Evt, Vt), St1),
- Mvt = vtmerge(Evt, Cvt),
- {Mvt,St2}.
-
-%% see icrt_clauses/4
-cond_cases(B, Cs, In, Vt, St0) ->
- %% note that Vt is used for both cases
- {Bvt,St1} = exprs(B, Vt, St0), % true case
- Vt1 = vtupdate(Bvt, Vt),
- {Cvt, St2} = cond_clauses(Cs, In, Vt, St1), % false case
- Vt2 = vtupdate(Cvt, Vt),
- %% and this also uses Vt
- icrt_export([Vt1,Vt2], Vt, In, St2).
-
-%% last case must call icrt_export/4 with only one vartable
-last_cond_clause({clause,_L,[],[[E]],B}, In, Vt, St0) ->
- {Evt,St1} = expr(E, Vt, St0),
- {Cvt, St2} = last_cond_case(B, In, vtupdate(Evt, Vt), St1),
- Mvt = vtmerge(Evt, Cvt),
- {Mvt,St2}.
-
-last_cond_case(B, In, Vt, St0) ->
- {Bvt,St1} = exprs(B, Vt, St0),
- Vt1 = vtupdate(Bvt, Vt),
- icrt_export([Vt1], Vt, In, St1).
-
icrt_export(Csvt, Vt, In, St) ->
Vt1 = vtmerge(Csvt),
All = ordsets:subtract(vintersection(Csvt), vtnames(Vt)),
diff --git a/lib/stdlib/src/erl_parse.yrl b/lib/stdlib/src/erl_parse.yrl
index fd5d905797..ea91ec5927 100644
--- a/lib/stdlib/src/erl_parse.yrl
+++ b/lib/stdlib/src/erl_parse.yrl
@@ -1,20 +1,20 @@
%% -*- erlang -*-
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -57,7 +57,6 @@ char integer float atom string var
'(' ')' ',' '->' ':-' '{' '}' '[' ']' '|' '||' '<-' ';' ':' '#' '.'
'after' 'begin' 'case' 'try' 'catch' 'end' 'fun' 'if' 'of' 'receive' 'when'
'andalso' 'orelse' 'query' 'spec'
-%% 'cond'
'bnot' 'not'
'*' '/' 'div' 'rem' 'band' 'and'
'+' '-' 'bor' 'bxor' 'bsl' 'bsr' 'or' 'xor'
@@ -422,14 +421,6 @@ try_clause -> var ':' expr clause_guard clause_body :
L = ?line('$1'),
{clause,L,[{tuple,L,['$1','$3',{var,L,'_'}]}],'$4','$5'}.
-%%cond_expr -> 'cond' cond_clauses 'end' : {'cond',?line('$1'),'$2'}.
-
-%%cond_clauses -> cond_clause : ['$1'].
-%%cond_clauses -> cond_clause ';' cond_clauses : ['$1' | '$3'].
-
-%%cond_clause -> expr clause_body :
-%% {clause,?line('$1'),[],[['$1']],'$2'}.
-
query_expr -> 'query' list_comprehension 'end' :
{'query',?line('$1'),'$2'}.
@@ -743,13 +734,29 @@ record_fields([{typed,Expr,TypeInfo}|Fields]) ->
case Expr of
{match, _, _, _} -> TypeInfo; %% If we have an initializer.
{atom, La, _} ->
- lift_unions(abstract(undefined, La), TypeInfo)
+ case has_undefined(TypeInfo) of
+ false ->
+ lift_unions(abstract(undefined, La), TypeInfo);
+ true ->
+ TypeInfo
+ end
end,
[{typed_record_field,Field,TypeInfo1}|record_fields(Fields)];
record_fields([Other|_Fields]) ->
ret_err(?line(Other), "bad record field");
record_fields([]) -> [].
+has_undefined({atom,_,undefined}) ->
+ true;
+has_undefined({ann_type,_,[_,T]}) ->
+ has_undefined(T);
+has_undefined({paren_type,_,[T]}) ->
+ has_undefined(T);
+has_undefined({type,_,union,Ts}) ->
+ lists:any(fun has_undefined/1, Ts);
+has_undefined(_) ->
+ false.
+
term(Expr) ->
try normalise(Expr)
catch _:_R -> ret_err(?line(Expr), "bad attribute")
diff --git a/lib/stdlib/src/escript.erl b/lib/stdlib/src/escript.erl
index 5958a58d7c..d26443f277 100644
--- a/lib/stdlib/src/escript.erl
+++ b/lib/stdlib/src/escript.erl
@@ -19,11 +19,16 @@
-module(escript).
%% Useful functions that can be called from scripts.
--export([script_name/0, foldl/3]).
+-export([script_name/0, create/2, extract/2]).
%% Internal API.
-export([start/0, start/1]).
+-include_lib("kernel/include/file.hrl").
+
+-define(SHEBANG, "/usr/bin/env escript").
+-define(COMMENT, "This is an -*- erlang -*- file").
+
-record(state, {file,
module,
forms_or_bin,
@@ -32,89 +37,223 @@
mode,
exports_main,
has_records}).
-
+-record(sections, {type,
+ shebang,
+ comment,
+ emu_args,
+ body}).
+-record(extract_options, {compile_source}).
+
+-type shebang() :: string().
+-type comment() :: string().
+-type emu_args() :: string().
+-type escript_filename() :: string().
+-type filename() :: string().
+-type zip_file() ::
+ filename()
+ | {filename(), binary()}
+ | {filename(), binary(), #file_info{}}.
+-type zip_create_option() :: term().
+-type section() ::
+ shebang
+ | {shebang, shebang()}
+ | comment
+ | {comment, comment()}
+ | {emu_args, emu_args()}
+ | {source, filename() | binary()}
+ | {beam, filename() | binary()}
+ | {archive, filename() | binary()}
+ | {archive, [zip_file()], [zip_create_option()]}.
+
+%% Create a complete escript file with both header and body
+-spec create(escript_filename() | binary, [section()]) ->
+ ok | {ok, binary()} | {error, term()}.
+
+create(File, Options) when is_list(Options) ->
+ try
+ S = prepare(Options, #sections{}),
+ BinList =
+ [Section || Section <- [S#sections.shebang,
+ S#sections.comment,
+ S#sections.emu_args,
+ S#sections.body],
+ Section =/= undefined],
+ case File of
+ binary ->
+ {ok, list_to_binary(BinList)};
+ _ ->
+ case file:write_file(File, BinList) of
+ ok ->
+ ok;
+ {error, Reason} ->
+ {error, {Reason, File}}
+ end
+ end
+ catch
+ throw:PrepareReason ->
+ {error, PrepareReason}
+ end.
+
+prepare([H | T], S) ->
+ case H of
+ {shebang, undefined} ->
+ prepare(T, S);
+ shebang ->
+ prepare(T, S#sections{shebang = "#!" ++ ?SHEBANG ++ "\n"});
+ {shebang, default} ->
+ prepare(T, S#sections{shebang = "#!" ++ ?SHEBANG ++ "\n"});
+ {shebang, Shebang} when is_list(Shebang) ->
+ prepare(T, S#sections{shebang = "#!" ++ Shebang ++ "\n"});
+ {comment, undefined} ->
+ prepare(T, S);
+ comment ->
+ prepare(T, S#sections{comment = "%% " ++ ?COMMENT ++ "\n"});
+ {comment, default} ->
+ prepare(T, S#sections{comment = "%% " ++ ?COMMENT ++ "\n"});
+ {comment, Comment} when is_list(Comment) ->
+ prepare(T, S#sections{comment = "%% " ++ Comment ++ "\n"});
+ {emu_args, undefined} ->
+ prepare(T, S);
+ {emu_args, Args} when is_list(Args) ->
+ prepare(T, S#sections{emu_args = "%%!" ++ Args ++ "\n"});
+ {Type, File} when is_list(File) ->
+ case file:read_file(File) of
+ {ok, Bin} ->
+ prepare(T, S#sections{type = Type, body = Bin});
+ {error, Reason} ->
+ throw({Reason, H})
+ end;
+ {Type, Bin} when is_binary(Bin) ->
+ prepare(T, S#sections{type = Type, body = Bin});
+ {archive = Type, ZipFiles, ZipOptions}
+ when is_list(ZipFiles), is_list(ZipOptions) ->
+ File = "dummy.zip",
+ case zip:create(File, ZipFiles, ZipOptions ++ [memory]) of
+ {ok, {File, ZipBin}} ->
+ prepare(T, S#sections{type = Type, body = ZipBin});
+ {error, Reason} ->
+ throw({Reason, H})
+ end;
+ _ ->
+ throw({badarg, H})
+ end;
+prepare([], #sections{body = undefined}) ->
+ throw(missing_body);
+prepare([], #sections{type = Type} = S)
+ when Type =:= source; Type =:= beam; Type =:= archive ->
+ S;
+prepare([], #sections{type = Type}) ->
+ throw({illegal_type, Type});
+prepare(BadOptions, _) ->
+ throw({badarg, BadOptions}).
+
+-type section_name() :: shebang | comment | emu_args | body .
+-type extract_option() :: compile_source | {section, [section_name()]}.
+-spec extract(filename(), [extract_option()]) -> {ok, [section()]} | {error, term()}.
+extract(File, Options) when is_list(File), is_list(Options) ->
+ try
+ EO = parse_extract_options(Options,
+ #extract_options{compile_source = false}),
+ {HeaderSz, NextLineNo, Fd, Sections} =
+ parse_header(File, not EO#extract_options.compile_source),
+ Type = Sections#sections.type,
+ case {Type, EO#extract_options.compile_source} of
+ {source, true} ->
+ Bin = compile_source(Type, File, Fd, NextLineNo, HeaderSz);
+ {_, _} ->
+ ok = file:close(Fd),
+ case file:read_file(File) of
+ {ok, <<_Header:HeaderSz/binary, Bin/binary>>} ->
+ ok;
+ {error, ReadReason} ->
+ Bin = get_rid_of_compiler_warning,
+ throw(ReadReason)
+ end
+ end,
+ return_sections(Sections, Bin)
+ catch
+ throw:Reason ->
+ {error, Reason}
+ end.
+
+parse_extract_options([H | T], EO) ->
+ case H of
+ compile_source ->
+ EO2 = EO#extract_options{compile_source = true},
+ parse_extract_options(T, EO2);
+ _ ->
+ throw({badarg, H})
+ end;
+parse_extract_options([], EO) ->
+ EO.
+
+compile_source(Type, File, Fd, NextLineNo, HeaderSz) ->
+ {text, _Module, Forms, _HasRecs, _Mode} =
+ do_parse_file(Type, File, Fd, NextLineNo, HeaderSz, false),
+ ok = file:close(Fd),
+ case compile:forms(Forms, [return_errors, debug_info]) of
+ {ok, _, BeamBin} ->
+ BeamBin;
+ {error, Errors, Warnings} ->
+ throw({compile, [{errors, format_errors(Errors)},
+ {warnings, format_errors(Warnings)}]})
+ end.
+
+format_errors(CompileErrors) ->
+ [lists:flatten([File, ":", integer_to_list(LineNo), ": ",
+ Mod:format_error(Error)]) ||
+ {File, FileErrors} <- CompileErrors,
+ {LineNo, Mod, Error} <- FileErrors].
+
+return_sections(S, Bin) ->
+ {ok, [normalize_section(shebang, S#sections.shebang),
+ normalize_section(comment, S#sections.comment),
+ normalize_section(emu_args, S#sections.emu_args),
+ normalize_section(S#sections.type, Bin)]}.
+
+normalize_section(Name, undefined) ->
+ {Name, undefined};
+normalize_section(shebang, "#!" ++ Chars) ->
+ Chopped = string:strip(Chars, right, $\n),
+ Stripped = string:strip(Chopped, both),
+ if
+ Stripped =:= ?SHEBANG ->
+ {shebang, default};
+ true ->
+ {shebang, Stripped}
+ end;
+normalize_section(comment, Chars) ->
+ Chopped = string:strip(Chars, right, $\n),
+ Stripped = string:strip(string:strip(Chopped, left, $%), both),
+ if
+ Stripped =:= ?COMMENT ->
+ {comment, default};
+ true ->
+ {comment, Stripped}
+ end;
+normalize_section(emu_args, "%%!" ++ Chars) ->
+ Chopped = string:strip(Chars, right, $\n),
+ Stripped = string:strip(Chopped, both),
+ {emu_args, Stripped};
+normalize_section(Name, Chars) ->
+ {Name, Chars}.
+
+-spec script_name() -> string().
script_name() ->
[ScriptName|_] = init:get_plain_arguments(),
ScriptName.
-%% Apply Fun(Name, GetInfo, GetBin, Acc) for each file in the escript.
-%%
-%% Fun/2 must return a new accumulator which is passed to the next call.
-%% The function returns the final value of the accumulator. Acc0 is
-%% returned if the escript contain an empty archive.
-%%
-%% GetInfo/0 is a fun that returns a #file_info{} record for the file.
-%% GetBin/0 is a fun that returns a the contents of the file as a binary.
-%%
-%% An escript may contain erlang code, beam code or an archive:
-%%
-%% archive - the Fun/2 will be applied for each file in the archive
-%% beam - the Fun/2 will be applied once and GetInfo/0 returns the file
-%% info for the (entire) escript file
-%% erl - the Fun/2 will be applied once, GetInfo/0 returns the file
-%% info for the (entire) escript file and the GetBin returns
-%% the compiled beam code
-
-%%-spec foldl(fun((string(),
-%% fun(() -> #file_info()),
-%% fun(() -> binary() -> term()),
-%% term()) -> term()),
-%% term(),
-%% string()).
-foldl(Fun, Acc0, File) when is_function(Fun, 4) ->
- case parse_file(File, false) of
- {text, _, Forms, _HasRecs, _Mode} when is_list(Forms) ->
- GetInfo = fun() -> file:read_file_info(File) end,
- GetBin =
- fun() ->
- case compile:forms(Forms, [return_errors, debug_info]) of
- {ok, _, BeamBin} ->
- BeamBin;
- {error, _Errors, _Warnings} ->
- fatal("There were compilation errors.")
- end
- end,
- try
- {ok, Fun(".", GetInfo, GetBin, Acc0)}
- catch
- throw:Reason ->
- {error, Reason}
- end;
- {beam, _, BeamBin, _HasRecs, _Mode} when is_binary(BeamBin) ->
- GetInfo = fun() -> file:read_file_info(File) end,
- GetBin = fun() -> BeamBin end,
- try
- {ok, Fun(".", GetInfo, GetBin, Acc0)}
- catch
- throw:Reason ->
- {error, Reason}
- end;
- {archive, _, ArchiveBin, _HasRecs, _Mode} when is_binary(ArchiveBin) ->
- ZipFun =
- fun({Name, GetInfo, GetBin}, A) ->
- A2 = Fun(Name, GetInfo, GetBin, A),
- {true, false, A2}
- end,
- case prim_zip:open(ZipFun, Acc0, {File, ArchiveBin}) of
- {ok, PrimZip, Res} ->
- ok = prim_zip:close(PrimZip),
- {ok, Res};
- {error, bad_eocd} ->
- {error, "Not an archive file"};
- {error, Reason} ->
- {error, Reason}
- end
- end.
-
%%
%% Internal API.
%%
+-spec start() -> no_return().
start() ->
start([]).
+-spec start([string()]) -> no_return().
start(EscriptOptions) ->
- try
+ try
%% Commands run using -run or -s are run in a process
%% trap_exit set to false. Because this behaviour is
%% surprising for users of escript, make sure to reset
@@ -143,11 +282,11 @@ parse_and_run(File, Args, Options) ->
parse_file(File, CheckOnly),
Mode2 =
case lists:member("d", Options) of
- true ->
+ true ->
debug;
false ->
case lists:member("c", Options) of
- true ->
+ true ->
compile;
false ->
case lists:member("i", Options) of
@@ -177,7 +316,7 @@ parse_and_run(File, Args, Options) ->
_Other ->
fatal("There were compilation errors.")
end
- end;
+ end;
is_binary(FormsOrBin) ->
case Source of
archive ->
@@ -190,11 +329,13 @@ parse_and_run(File, Args, Options) ->
true ->
my_halt(0);
false ->
- Text = lists:concat(["Function ", Module, ":main/1 is not exported"]),
+ Text = lists:concat(["Function ", Module,
+ ":main/1 is not exported"]),
fatal(Text)
end;
_ ->
- Text = lists:concat(["Cannot load module ", Module, " from archive"]),
+ Text = lists:concat(["Cannot load module ", Module,
+ " from archive"]),
fatal(Text)
end;
ok ->
@@ -212,7 +353,7 @@ parse_and_run(File, Args, Options) ->
run ->
{module, Module} = code:load_binary(Module, File, FormsOrBin),
run(Module, Args);
- debug ->
+ debug ->
[Base | Rest] = lists:reverse(filename:split(File)),
Base2 = filename:basename(Base, code:objfile_extension()),
Rest2 =
@@ -222,8 +363,8 @@ parse_and_run(File, Args, Options) ->
end,
SrcFile = filename:join(lists:reverse([Base2 ++ ".erl" | Rest2])),
debug(Module, {Module, SrcFile, File, FormsOrBin}, Args)
- end
- end
+ end
+ end
end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -231,25 +372,19 @@ parse_and_run(File, Args, Options) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
parse_file(File, CheckOnly) ->
- S = #state{file = File,
- n_errors = 0,
- mode = interpret,
- exports_main = false,
- has_records = false},
- {ok, Fd} =
- case file:open(File, [read]) of
- {ok, Fd0} ->
- {ok, Fd0};
- {error, R} ->
- fatal(lists:concat([file:format_error(R), ": '", File, "'"]))
- end,
- {HeaderSz, StartLine, ScriptType} = skip_header(Fd, 1),
+ {HeaderSz, NextLineNo, Fd, Sections} =
+ parse_header(File, false),
+ do_parse_file(Sections#sections.type,
+ File, Fd, NextLineNo, HeaderSz, CheckOnly).
+
+do_parse_file(Type, File, Fd, NextLineNo, HeaderSz, CheckOnly) ->
+ S = initial_state(File),
#state{mode = Mode,
source = Source,
module = Module,
forms_or_bin = FormsOrBin,
has_records = HasRecs} =
- case ScriptType of
+ case Type of
archive ->
%% Archive file
ok = file:close(Fd),
@@ -260,51 +395,93 @@ parse_file(File, CheckOnly) ->
parse_beam(S, File, HeaderSz, CheckOnly);
source ->
%% Source code
- parse_source(S, File, Fd, StartLine, HeaderSz, CheckOnly)
+ parse_source(S, File, Fd, NextLineNo, HeaderSz, CheckOnly)
end,
{Source, Module, FormsOrBin, HasRecs, Mode}.
+initial_state(File) ->
+ #state{file = File,
+ n_errors = 0,
+ mode = interpret,
+ exports_main = false,
+ has_records = false}.
+
%% Skip header and make a heuristic guess about the script type
-skip_header(P, LineNo) ->
+parse_header(File, KeepFirst) ->
+ LineNo = 1,
+ {ok, Fd} =
+ case file:open(File, [read]) of
+ {ok, Fd0} ->
+ {ok, Fd0};
+ {error, R} ->
+ fatal(lists:concat([file:format_error(R), ": '", File, "'"]))
+ end,
+
%% Skip shebang on first line
- {ok, HeaderSz0} = file:position(P, cur),
- Line1 = get_line(P),
+ {ok, HeaderSz0} = file:position(Fd, cur),
+ Line1 = get_line(Fd),
case classify_line(Line1) of
shebang ->
- find_first_body_line(P, LineNo);
+ find_first_body_line(Fd, HeaderSz0, LineNo, KeepFirst,
+ #sections{shebang = Line1});
archive ->
- {HeaderSz0, LineNo, archive};
+ {HeaderSz0, LineNo, Fd,
+ #sections{type = archive}};
beam ->
- {HeaderSz0, LineNo, beam};
+ {HeaderSz0, LineNo, Fd,
+ #sections{type = beam}};
_ ->
- find_first_body_line(P, LineNo)
+ find_first_body_line(Fd, HeaderSz0, LineNo, KeepFirst,
+ #sections{})
end.
-find_first_body_line(P, LineNo) ->
- {ok, HeaderSz1} = file:position(P, cur),
+find_first_body_line(Fd, HeaderSz0, LineNo, KeepFirst, Sections) ->
+ {ok, HeaderSz1} = file:position(Fd, cur),
%% Look for special comment on second line
- Line2 = get_line(P),
- {ok, HeaderSz2} = file:position(P, cur),
+ Line2 = get_line(Fd),
+ {ok, HeaderSz2} = file:position(Fd, cur),
case classify_line(Line2) of
emu_args ->
%% Skip special comment on second line
- Line3 = get_line(P),
- {HeaderSz2, LineNo + 2, guess_type(Line3)};
- _ ->
+ Line3 = get_line(Fd),
+ {HeaderSz2, LineNo + 2, Fd,
+ Sections#sections{type = guess_type(Line3),
+ comment = undefined,
+ emu_args = Line2}};
+ Line2Type ->
%% Look for special comment on third line
- Line3 = get_line(P),
- {ok, HeaderSz3} = file:position(P, cur),
- case classify_line(Line3) of
- emu_args ->
+ Line3 = get_line(Fd),
+ {ok, HeaderSz3} = file:position(Fd, cur),
+ Line3Type = classify_line(Line3),
+ if
+ Line3Type =:= emu_args ->
%% Skip special comment on third line
- Line4 = get_line(P),
- {HeaderSz3, LineNo + 3, guess_type(Line4)};
- _ ->
+ Line4 = get_line(Fd),
+ {HeaderSz3, LineNo + 3, Fd,
+ Sections#sections{type = guess_type(Line4),
+ comment = Line2,
+ emu_args = Line3}};
+ Sections#sections.shebang =:= undefined,
+ KeepFirst =:= true ->
+ %% No shebang. Use the entire file
+ {HeaderSz0, LineNo, Fd,
+ Sections#sections{type = guess_type(Line2)}};
+ Sections#sections.shebang =:= undefined ->
+ %% No shebang. Skip the first line
+ {HeaderSz1, LineNo, Fd,
+ Sections#sections{type = guess_type(Line2)}};
+ Line2Type =:= comment ->
+ %% Skip shebang on first line and comment on second
+ {HeaderSz2, LineNo + 2, Fd,
+ Sections#sections{type = guess_type(Line3),
+ comment = Line2}};
+ true ->
%% Just skip shebang on first line
- {HeaderSz1, LineNo + 1, guess_type(Line2)}
+ {HeaderSz1, LineNo + 1, Fd,
+ Sections#sections{type = guess_type(Line2)}}
end
end.
-
+
classify_line(Line) ->
case Line of
[$\#, $\! | _] ->
@@ -313,8 +490,10 @@ classify_line(Line) ->
archive;
[$F, $O, $R, $1 | _] ->
beam;
- [$\%, $\%, $\! | _] ->
+ [$%, $%, $\! | _] ->
emu_args;
+ [$% | _] ->
+ comment;
_ ->
undefined
end.
@@ -336,8 +515,8 @@ get_line(P) ->
parse_archive(S, File, HeaderSz) ->
case file:read_file(File) of
- {ok, <<_FirstLine:HeaderSz/binary, Bin/binary>>} ->
- Mod =
+ {ok, <<_Header:HeaderSz/binary, Bin/binary>>} ->
+ Mod =
case init:get_argument(escript) of
{ok, [["main", M]]} ->
%% Use explicit module name
@@ -345,14 +524,14 @@ parse_archive(S, File, HeaderSz) ->
_ ->
%% Use escript name without extension as module name
RevBase = lists:reverse(filename:basename(File)),
- RevBase2 =
+ RevBase2 =
case lists:dropwhile(fun(X) -> X =/= $. end, RevBase) of
[$. | Rest] -> Rest;
[] -> RevBase
end,
list_to_atom(lists:reverse(RevBase2))
end,
-
+
S#state{source = archive,
mode = run,
module = Mod,
@@ -365,7 +544,7 @@ parse_archive(S, File, HeaderSz) ->
parse_beam(S, File, HeaderSz, CheckOnly) ->
- {ok, <<_FirstLine:HeaderSz/binary, Bin/binary>>} =
+ {ok, <<_Header:HeaderSz/binary, Bin/binary>>} =
file:read_file(File),
case beam_lib:chunks(Bin, [exports]) of
{ok, {Module, [{exports, Exports}]}} ->
@@ -399,7 +578,7 @@ parse_source(S, File, Fd, StartLine, HeaderSz, CheckOnly) ->
{ok, FileForm} = epp:parse_erl_form(Epp),
OptModRes = epp:parse_erl_form(Epp),
S2 = S#state{source = text, module = Module},
- S3 =
+ S3 =
case OptModRes of
{ok, {attribute,_, module, M} = Form} ->
epp_parse_file(Epp, S2#state{module = M}, [Form, FileForm]);
@@ -448,12 +627,12 @@ check_source(S, CheckOnly) ->
pre_def_macros(File) ->
{MegaSecs, Secs, MicroSecs} = erlang:now(),
- Replace = fun(Char) ->
+ Replace = fun(Char) ->
case Char of
$\. -> $\_;
_ -> Char
end
- end,
+ end,
CleanBase = lists:map(Replace, filename:basename(File)),
ModuleStr =
CleanBase ++ "__" ++
@@ -642,8 +821,8 @@ eval_exprs([E|Es], Bs0, Lf, Ef, RBs) ->
eval_exprs(Es, Bs, Lf, Ef, RBs).
format_exception(Class, Reason) ->
- PF = fun(Term, I) ->
- io_lib:format("~." ++ integer_to_list(I) ++ "P", [Term, 50])
+ PF = fun(Term, I) ->
+ io_lib:format("~." ++ integer_to_list(I) ++ "P", [Term, 50])
end,
StackTrace = erlang:get_stacktrace(),
StackFun = fun(M, _F, _A) -> (M =:= erl_eval) or (M =:= ?MODULE) end,
@@ -651,7 +830,7 @@ format_exception(Class, Reason) ->
fatal(Str) ->
throw(Str).
-
+
my_halt(Reason) ->
case process_info(group_leader(), status) of
{_,waiting} ->
@@ -675,7 +854,7 @@ hidden_apply(App, M, F, Args) ->
Arity = length(Args),
Text = io_lib:format("Call to ~w:~w/~w in application ~w failed.\n",
[M, F, Arity, App]),
- fatal(Text);
+ fatal(Text);
Stk ->
erlang:raise(error, undef, Stk)
end
diff --git a/lib/stdlib/src/zip.erl b/lib/stdlib/src/zip.erl
index e76d588cb5..d41aeefa59 100644
--- a/lib/stdlib/src/zip.erl
+++ b/lib/stdlib/src/zip.erl
@@ -20,7 +20,7 @@
%% Basic api
-export([unzip/1, unzip/2, extract/1, extract/2,
- zip/2, zip/3, create/2, create/3,
+ zip/2, zip/3, create/2, create/3, foldl/3,
list_dir/1, list_dir/2, table/1, table/2,
t/1, tt/1]).
@@ -38,7 +38,7 @@
zip_t/1, zip_tt/1,
zip_list_dir/1, zip_list_dir/2,
zip_close/1]).
-
+
%% just for debugging zip server, not documented, not tested, not to be used
-export([zip_get_state/1]).
@@ -82,7 +82,7 @@
-record(openzip_opts, {
output, % output object (fun)
open_opts, % file:open options
- cwd % directory to relate paths to
+ cwd % directory to relate paths to
}).
% openzip record, state for an open zip-file
@@ -93,10 +93,10 @@
input, % archive io object (fun)
output, % output io object (fun)
zlib, % handle to open zlib
- cwd % directory to relate paths to
+ cwd % directory to relate paths to
}).
-% Things that I would like to add to the public record #zip_file,
+% Things that I would like to add to the public record #zip_file,
% but can't as it would make things fail at upgrade.
% Instead we use {#zip_file,#zip_file_extra} internally.
-record(zip_file_extra, {
@@ -278,7 +278,7 @@ file_name_search(Name,Files) ->
[ZFile|_] -> ZFile;
[] -> false
end.
-
+
%% %% add a file to an open archive
%% openzip_add(File, OpenZip) ->
%% case ?CATCH do_openzip_add(File, OpenZip) of
@@ -344,6 +344,25 @@ do_unzip(F, Options) ->
Input(close, In1),
{ok, Files}.
+%% Iterate over all files in a zip archive
+foldl(Fun, Acc0, Archive) when is_function(Fun, 4) ->
+ ZipFun =
+ fun({Name, GetInfo, GetBin}, A) ->
+ A2 = Fun(Name, GetInfo, GetBin, A),
+ {true, false, A2}
+ end,
+ case prim_zip:open(ZipFun, Acc0, Archive) of
+ {ok, PrimZip, Acc1} ->
+ ok = prim_zip:close(PrimZip),
+ {ok, Acc1};
+ {error, bad_eocd} ->
+ {error, "Not an archive file"};
+ {error, Reason} ->
+ {error, Reason}
+ end;
+foldl(_,_, _) ->
+ {error, einval}.
+
%% Create zip archive name F from Files or binaries
%%
%% Accepted options:
@@ -383,7 +402,7 @@ list_dir(F, Options) ->
do_list_dir(F, Options) ->
Opts = get_list_dir_options(F, Options),
- #list_dir_opts{input = Input, open_opts = OpO,
+ #list_dir_opts{input = Input, open_opts = OpO,
raw_iterator = RawIterator} = Opts,
In0 = Input({open, F, OpO}, []),
{Info, In1} = get_central_dir(In0, RawIterator, Input),
@@ -417,7 +436,7 @@ tt(F) when is_record(F, openzip) -> openzip_tt(F);
tt(F) -> t(F, fun raw_long_print_info_etc/5).
-%% option utils
+%% option utils
get_unzip_opt([], Opts) ->
Opts;
get_unzip_opt([verbose | Rest], Opts) ->
@@ -470,7 +489,7 @@ get_zip_opt([{cwd, CWD} | Rest], Opts) ->
get_zip_opt([{comment, C} | Rest], Opts) ->
get_zip_opt(Rest, Opts#zip_opts{comment = C});
get_zip_opt([{compress, Which} = O| Rest], Opts) ->
- Which2 =
+ Which2 =
case Which of
all ->
all;
@@ -485,7 +504,7 @@ get_zip_opt([{compress, Which} = O| Rest], Opts) ->
end,
get_zip_opt(Rest, Opts#zip_opts{compress = Which2});
get_zip_opt([{uncompress, Which} = O| Rest], Opts) ->
- Which2 =
+ Which2 =
case Which of
all ->
all;
@@ -560,16 +579,24 @@ get_openzip_options(Options) ->
get_input(F) when is_binary(F) ->
fun binary_io/2;
get_input(F) when is_list(F) ->
- fun file_io/2.
+ fun file_io/2;
+get_input(_) ->
+ throw(einval).
get_zip_input({F, B}) when is_binary(B), is_list(F) ->
fun binary_io/2;
+get_zip_input({F, B, #file_info{}}) when is_binary(B), is_list(F) ->
+ fun binary_io/2;
+get_zip_input({F, #file_info{}, B}) when is_binary(B), is_list(F) ->
+ fun binary_io/2;
get_zip_input(F) when is_list(F) ->
fun file_io/2;
get_zip_input({files, []}) ->
fun binary_io/2;
get_zip_input({files, [File | _]}) ->
- get_zip_input(File).
+ get_zip_input(File);
+get_zip_input(_) ->
+ throw(einval).
get_list_dir_options(F, Options) ->
Opts = #list_dir_opts{raw_iterator = fun raw_file_info_public/5,
@@ -620,6 +647,8 @@ put_eocd(N, Pos, Sz, Comment, Output, Out0) ->
get_filename({Name, _}, Type) ->
get_filename(Name, Type);
+get_filename({Name, _, _}, Type) ->
+ get_filename(Name, Type);
get_filename(Name, regular) ->
Name;
get_filename(Name, directory) ->
@@ -895,7 +924,7 @@ local_file_header_to_bin(
CompSize:32/little,
UncompSize:32/little,
FileNameLength:16/little,
- ExtraFieldLength:16/little>>.
+ ExtraFieldLength:16/little>>.
eocd_to_bin(#eocd{disk_num = DiskNum,
start_disk_num = StartDiskNum,
@@ -912,7 +941,7 @@ eocd_to_bin(#eocd{disk_num = DiskNum,
Offset:32/little,
ZipCommentLength:16/little>>.
-%% put together a local file header
+%% put together a local file header
local_file_header_from_info_method_name(#file_info{mtime = MTime},
UncompSize,
CompMethod, Name) ->
@@ -939,7 +968,7 @@ server_loop(OpenZip) ->
server_loop(NewOpenZip);
Error ->
From ! {self(), Error}
- end;
+ end;
{From, close} ->
From ! {self(), openzip_close(OpenZip)};
{From, get} ->
@@ -1024,7 +1053,7 @@ lists_foreach(F, [Hd|Tl]) ->
F(Hd),
lists_foreach(F, Tl).
-%% option utils
+%% option utils
get_openzip_opt([], Opts) ->
Opts;
get_openzip_opt([cooked | Rest], #openzip_opts{open_opts = OO} = Opts) ->
@@ -1121,7 +1150,7 @@ raw_file_info_public(CD, FileName, FileComment, BExtraField, Acc0) ->
Other -> Other
end,
[H2|T].
-
+
%% make a file_info from a central directory header
cd_file_header_to_file_info(FileName,
@@ -1213,8 +1242,8 @@ get_z_file(In0, Z, Input, Output, OpO, FB, CWD, {ZipFile,Extra}) ->
{dir, In3};
_ ->
%% FileInfo = local_file_header_to_file_info(LH)
- %%{Out, In4, CRC, UncompSize} =
- {Out, In4, CRC, _UncompSize} =
+ %%{Out, In4, CRC, UncompSize} =
+ {Out, In4, CRC, _UncompSize} =
get_z_data(CompMethod, In3, FileName1,
CompSize, Input, Output, OpO, Z),
In5 = skip_z_data_descriptor(GPFlag, Input, In4),
@@ -1280,7 +1309,7 @@ get_z_data_loop(CompSize, UncompSize, In0, Out0, Input, Output, Z) ->
Out1 = Output({write, Uncompressed}, Out0),
get_z_data_loop(CompSize-N, UncompSize + iolist_size(Uncompressed),
In1, Out1, Input, Output, Z)
- end.
+ end.
%% skip data descriptor if any
@@ -1298,7 +1327,7 @@ dos_date_time_to_datetime(DosDate, DosTime) ->
<<Hour:5, Min:6, Sec:5>> = <<DosTime:16>>,
<<YearFrom1980:7, Month:4, Day:5>> = <<DosDate:16>>,
{{YearFrom1980+1980, Month, Day},
- {Hour, Min, Sec}}.
+ {Hour, Min, Sec}}.
dos_date_time_from_datetime({{Year, Month, Day}, {Hour, Min, Sec}}) ->
YearFrom1980 = Year-1980,
@@ -1319,7 +1348,6 @@ unix_extra_field_and_var_from_bin(<<TSize:16/little,
Var};
unix_extra_field_and_var_from_bin(_) ->
throw(bad_unix_extra_field).
-
%% A pwrite-like function for iolists (used by memory-option)
@@ -1478,6 +1506,8 @@ local_file_header_from_bin(_) ->
%% io functions
binary_io({file_info, {_Filename, _B, #file_info{} = FI}}, _A) ->
FI;
+binary_io({file_info, {_Filename, #file_info{} = FI, _B}}, _A) ->
+ FI;
binary_io({file_info, {_Filename, B}}, A) ->
binary_io({file_info, B}, A);
binary_io({file_info, B}, _) ->
@@ -1493,9 +1523,11 @@ binary_io({file_info, B}, _) ->
links = 1, major_device = 0,
minor_device = 0, inode = 0,
uid = 0, gid = 0};
-binary_io({open, {_Filename, B, _FI}, _Opts}, _) ->
+binary_io({open, {_Filename, B, _FI}, _Opts}, _) when is_binary(B) ->
+ {0, B};
+binary_io({open, {_Filename, _FI, B}, _Opts}, _) when is_binary(B) ->
{0, B};
-binary_io({open, {_Filename, B}, _Opts}, _) ->
+binary_io({open, {_Filename, B}, _Opts}, _) when is_binary(B) ->
{0, B};
binary_io({open, B, _Opts}, _) when is_binary(B) ->
{0, B};
diff --git a/lib/stdlib/test/erl_pp_SUITE.erl b/lib/stdlib/test/erl_pp_SUITE.erl
index a695374908..92a54108aa 100644
--- a/lib/stdlib/test/erl_pp_SUITE.erl
+++ b/lib/stdlib/test/erl_pp_SUITE.erl
@@ -46,7 +46,7 @@
neg_indent/1,
tickets/1,
otp_6321/1, otp_6911/1, otp_6914/1, otp_8150/1, otp_8238/1,
- otp_8473/1]).
+ otp_8473/1, otp_8522/1]).
%% Internal export.
-export([ehook/6]).
@@ -764,7 +764,7 @@ neg_indent(Config) when is_list(Config) ->
ok.
tickets(suite) ->
- [otp_6321, otp_6911, otp_6914, otp_8150, otp_8238, otp_8473].
+ [otp_6321, otp_6911, otp_6914, otp_8150, otp_8238, otp_8473, otp_8522].
otp_6321(doc) ->
"OTP_6321. Bug fix of exprs().";
@@ -847,7 +847,7 @@ type_examples() ->
{ex4,<<"-type t1() :: atom(). ">>},
{ex5,<<"-type t2() :: [t1()]. ">>},
{ex6,<<"-type t3(Atom) :: integer(Atom). ">>},
- {ex7,<<"-type t4() :: t3(foobar). ">>},
+ {ex7,<<"-type '\\'t::4'() :: t3('\\'foobar'). ">>},
{ex8,<<"-type t5() :: {t1(), t3(foo)}. ">>},
{ex9,<<"-type t6() :: 1 | 2 | 3 | 'foo' | 'bar'. ">>},
{ex10,<<"-type t7() :: []. ">>},
@@ -883,16 +883,16 @@ type_examples() ->
"1|2|3|4|a|b|c|d| "
"nonempty_maybe_improper_list(integer, any())]}. ">>},
{ex30,<<"-type t99() ::"
- "{t2(),t4(),t5(),t6(),t7(),t8(),t10(),t14(),"
+ "{t2(),'\\'t::4'(),t5(),t6(),t7(),t8(),t10(),t14(),"
"t15(),t20(),t21(), t22(),t25()}. ">>},
{ex31,<<"-spec t1(FooBar :: t99()) -> t99();"
"(t2()) -> t2();"
- "(t4()) -> t4() when is_subtype(t4(), t24);"
+ "('\\'t::4'()) -> '\\'t::4'() when is_subtype('\\'t::4'(), t24);"
"(t23()) -> t23() when is_subtype(t23(), atom()),"
" is_subtype(t23(), t14());"
"(t24()) -> t24() when is_subtype(t24(), atom()),"
" is_subtype(t24(), t14()),"
- " is_subtype(t24(), t4()).">>},
+ " is_subtype(t24(), '\\'t::4'()).">>},
{ex32,<<"-spec mod:t2() -> any(). ">>},
{ex33,<<"-opaque attributes_data() :: "
"[{'column', column()} | {'line', info_line()} |"
@@ -922,6 +922,33 @@ otp_8473(Config) when is_list(Config) ->
{N,B} <- Ex],
ok.
+otp_8522(doc) ->
+ "OTP_8522. Avoid duplicated 'undefined' in record field types.";
+otp_8522(suite) -> [];
+otp_8522(Config) when is_list(Config) ->
+ FileName = filename('otp_8522.erl', Config),
+ C = <<"-module(otp_8522).\n"
+ "-record(r, {f1 :: undefined,\n"
+ " f2 :: A :: undefined,\n"
+ " f3 :: (undefined),\n"
+ " f4 :: x | y | undefined | z,\n"
+ " f5 :: a}).\n">>,
+ ?line ok = file:write_file(FileName, C),
+ ?line {ok, _} = compile:file(FileName, [{outdir,?privdir},debug_info]),
+ BF = filename("otp_8522", Config),
+ ?line {ok, A} = beam_lib:chunks(BF, [abstract_code]),
+ ?line 5 = count_atom(A, undefined),
+ ok.
+
+count_atom(A, A) ->
+ 1;
+count_atom(T, A) when is_tuple(T) ->
+ count_atom(tuple_to_list(T), A);
+count_atom(L, A) when is_list(L) ->
+ lists:sum([count_atom(T, A) || T <- L]);
+count_atom(_, _) ->
+ 0.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
compile(Config, Tests) ->
diff --git a/lib/stdlib/test/escript_SUITE.erl b/lib/stdlib/test/escript_SUITE.erl
index f36ae34633..77fd190e45 100644
--- a/lib/stdlib/test/escript_SUITE.erl
+++ b/lib/stdlib/test/escript_SUITE.erl
@@ -22,16 +22,20 @@
init_per_testcase/2,
fin_per_testcase/2,
basic/1,
- errors/1,
+ errors/1,
strange_name/1,
emulator_flags/1,
module_script/1,
beam_script/1,
archive_script/1,
- epp/1
+ epp/1,
+ create_and_extract/1,
+ foldl/1,
+ verify_sections/3
]).
-include("test_server.hrl").
+-include_lib("kernel/include/file.hrl").
all(suite) ->
[
@@ -42,7 +46,9 @@ all(suite) ->
module_script,
beam_script,
archive_script,
- epp
+ epp,
+ create_and_extract,
+ foldl
].
init_per_testcase(_Case, Config) ->
@@ -68,11 +74,11 @@ basic(Config) when is_list(Config) ->
?line run(Dir, "factorial_warning 20",
[data_dir,<<"factorial_warning:12: Warning: function bar/0 is unused\n"
"factorial 20 = 2432902008176640000\nExitCode:0">>]),
- ?line run(Dir, "-s", "factorial_warning",
+ ?line run_with_opts(Dir, "-s", "factorial_warning",
[data_dir,<<"factorial_warning:12: Warning: function bar/0 is unused\nExitCode:0">>]),
- ?line run(Dir, "-s -i", "factorial_warning",
+ ?line run_with_opts(Dir, "-s -i", "factorial_warning",
[data_dir,<<"factorial_warning:12: Warning: function bar/0 is unused\nExitCode:0">>]),
- ?line run(Dir, "-c -s", "factorial_warning",
+ ?line run_with_opts(Dir, "-c -s", "factorial_warning",
[data_dir,<<"factorial_warning:12: Warning: function bar/0 is unused\nExitCode:0">>]),
?line run(Dir, "filesize "++filename:join(?config(data_dir, Config),"filesize"),
[data_dir,<<"filesize:11: Warning: function id/1 is unused\n324\nExitCode:0">>]),
@@ -100,7 +106,7 @@ errors(Config) when is_list(Config) ->
[data_dir,<<"lint_error:6: function main/1 already defined\n">>,
data_dir,"lint_error:8: variable 'ExitCode' is unbound\n",
<<"escript: There were compilation errors.\nExitCode:127">>]),
- ?line run(Dir, "-s", "lint_error",
+ ?line run_with_opts(Dir, "-s", "lint_error",
[data_dir,<<"lint_error:6: function main/1 already defined\n">>,
data_dir,"lint_error:8: variable 'ExitCode' is unbound\n",
<<"escript: There were compilation errors.\nExitCode:127">>]),
@@ -140,31 +146,31 @@ module_script(Config) when is_list(Config) ->
OrigFile = filename:join([Data,"emulator_flags"]),
{ok, OrigBin} = file:read_file(OrigFile),
?line [Shebang, Mode, Flags | Source] = string:tokens(binary_to_list(OrigBin), "\n"),
- ?line {ok, OrigFI} = file:read_file_info(OrigFile),
+ ?line {ok, OrigFI} = file:read_file_info(OrigFile),
%% Write source file
Priv = ?config(priv_dir, Config),
Dir = filename:absname(Priv), % Get rid of trailing slash.
Base = "module_script",
ErlFile = filename:join([Priv, Base ++ ".erl"]),
- ErlCode = ["-module(", Base, ").\n",
+ ErlCode = ["\n-module(", Base, ").\n",
"-export([main/1]).\n\n",
string:join(Source, "\n"),
"\n"],
?line ok = file:write_file(ErlFile, ErlCode),
-
+
%%%%%%%
%% Create and run scripts without emulator flags
%% With shebang
NoArgsBase = Base ++ "_no_args_with_shebang",
NoArgsFile = filename:join([Priv, NoArgsBase]),
- ?line ok = file:write_file(NoArgsFile,
+ ?line ok = file:write_file(NoArgsFile,
[Shebang, "\n",
ErlCode]),
?line ok = file:write_file_info(NoArgsFile, OrigFI),
-
- ?line run(Dir, NoArgsBase ++ " -arg1 arg2 arg3",
+
+ ?line run(Dir, NoArgsBase ++ " -arg1 arg2 arg3",
[<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n"
"nostick:[]\n"
"mnesia:[]\n"
@@ -172,7 +178,7 @@ module_script(Config) when is_list(Config) ->
"unknown:[]\n"
"ExitCode:0">>]),
- ?line run(Dir, "", NoArgsBase ++ " -arg1 arg2 arg3",
+ ?line run_with_opts(Dir, "", NoArgsBase ++ " -arg1 arg2 arg3",
[<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n"
"nostick:[]\n"
"mnesia:[]\n"
@@ -183,33 +189,33 @@ module_script(Config) when is_list(Config) ->
%% Without shebang
NoArgsBase2 = Base ++ "_no_args_without_shebang",
NoArgsFile2 = filename:join([Priv, NoArgsBase2]),
- ?line ok = file:write_file(NoArgsFile2,
+ ?line ok = file:write_file(NoArgsFile2,
["Something else than shebang!!!", "\n",
ErlCode]),
?line ok = file:write_file_info(NoArgsFile2, OrigFI),
-
- ?line run(Dir, "", NoArgsBase2 ++ " -arg1 arg2 arg3",
+
+ ?line run_with_opts(Dir, "", NoArgsBase2 ++ " -arg1 arg2 arg3",
[<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n"
"nostick:[]\n"
"mnesia:[]\n"
"ERL_FLAGS=false\n"
"unknown:[]\n"
"ExitCode:0">>]),
-
+
%% Plain module without header
NoArgsBase3 = Base ++ "_no_args_without_header",
NoArgsFile3 = filename:join([Priv, NoArgsBase3]),
?line ok = file:write_file(NoArgsFile3, [ErlCode]),
?line ok = file:write_file_info(NoArgsFile3, OrigFI),
-
- ?line run(Dir, "", NoArgsBase3 ++ " -arg1 arg2 arg3",
+
+ ?line run_with_opts(Dir, "", NoArgsBase3 ++ " -arg1 arg2 arg3",
[<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n"
"nostick:[]\n"
"mnesia:[]\n"
"ERL_FLAGS=false\n"
"unknown:[]\n"
"ExitCode:0">>]),
-
+
%%%%%%%
%% Create and run scripts with emulator flags
@@ -217,12 +223,12 @@ module_script(Config) when is_list(Config) ->
ArgsBase = Base ++ "_args_with_shebang",
ArgsFile = filename:join([Priv, ArgsBase]),
?line ok = file:write_file(ArgsFile,
- [Shebang, "\n",
+ [Shebang, "\n",
Mode, "\n",
Flags, "\n",
ErlCode]),
- ?line ok = file:write_file_info(ArgsFile, OrigFI),
-
+ ?line ok = file:write_file_info(ArgsFile, OrigFI),
+
?line run(Dir, ArgsBase ++ " -arg1 arg2 arg3",
[<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n"
"nostick:[{nostick,[]}]\n"
@@ -242,32 +248,32 @@ beam_script(Config) when is_list(Config) ->
OrigFile = filename:join([Data,"emulator_flags"]),
{ok, OrigBin} = file:read_file(OrigFile),
?line [Shebang, Mode, Flags | Source] = string:tokens(binary_to_list(OrigBin), "\n"),
- ?line {ok, OrigFI} = file:read_file_info(OrigFile),
+ ?line {ok, OrigFI} = file:read_file_info(OrigFile),
%% Write source file
Priv = ?config(priv_dir, Config),
Dir = filename:absname(Priv), % Get rid of trailing slash.
Base = "beam_script",
ErlFile = filename:join([Priv, Base ++ ".erl"]),
- ?line ok = file:write_file(ErlFile,
- ["-module(", Base, ").\n",
+ ?line ok = file:write_file(ErlFile,
+ ["\n-module(", Base, ").\n",
"-export([main/1]).\n\n",
string:join(Source, "\n"),
"\n"]),
%% Compile the code
?line {ok, _Mod, BeamCode} = compile:file(ErlFile, [binary]),
-
+
%%%%%%%
%% Create and run scripts without emulator flags
%% With shebang
NoArgsBase = Base ++ "_no_args_with_shebang",
NoArgsFile = filename:join([Priv, NoArgsBase]),
- ?line ok = file:write_file(NoArgsFile,
+ ?line ok = file:write_file(NoArgsFile,
[Shebang, "\n",
BeamCode]),
- ?line ok = file:write_file_info(NoArgsFile, OrigFI),
+ ?line ok = file:write_file_info(NoArgsFile, OrigFI),
?line run(Dir, NoArgsBase ++ " -arg1 arg2 arg3",
[<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n"
@@ -277,7 +283,7 @@ beam_script(Config) when is_list(Config) ->
"unknown:[]\n"
"ExitCode:0">>]),
- ?line run(Dir, "", NoArgsBase ++ " -arg1 arg2 arg3",
+ ?line run_with_opts(Dir, "", NoArgsBase ++ " -arg1 arg2 arg3",
[<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n"
"nostick:[]\n"
"mnesia:[]\n"
@@ -288,12 +294,12 @@ beam_script(Config) when is_list(Config) ->
%% Without shebang
NoArgsBase2 = Base ++ "_no_args_without_shebang",
NoArgsFile2 = filename:join([Priv, NoArgsBase2]),
- ?line ok = file:write_file(NoArgsFile2,
+ ?line ok = file:write_file(NoArgsFile2,
["Something else than shebang!!!", "\n",
BeamCode]),
- ?line ok = file:write_file_info(NoArgsFile2, OrigFI),
+ ?line ok = file:write_file_info(NoArgsFile2, OrigFI),
- ?line run(Dir, "", NoArgsBase2 ++ " -arg1 arg2 arg3",
+ ?line run_with_opts(Dir, "", NoArgsBase2 ++ " -arg1 arg2 arg3",
[<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n"
"nostick:[]\n"
"mnesia:[]\n"
@@ -305,9 +311,9 @@ beam_script(Config) when is_list(Config) ->
NoArgsBase3 = Base ++ "_no_args_without_header",
NoArgsFile3 = filename:join([Priv, NoArgsBase3]),
?line ok = file:write_file(NoArgsFile3, [BeamCode]),
- ?line ok = file:write_file_info(NoArgsFile3, OrigFI),
+ ?line ok = file:write_file_info(NoArgsFile3, OrigFI),
- ?line run(Dir, "", NoArgsBase3 ++ " -arg1 arg2 arg3",
+ ?line run_with_opts(Dir, "", NoArgsBase3 ++ " -arg1 arg2 arg3",
[<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n"
"nostick:[]\n"
"mnesia:[]\n"
@@ -322,12 +328,12 @@ beam_script(Config) when is_list(Config) ->
ArgsBase = Base ++ "_args",
ArgsFile = filename:join([Priv, ArgsBase]),
?line ok = file:write_file(ArgsFile,
- [Shebang, "\n",
+ [Shebang, "\n",
Mode, "\n",
Flags, "\n",
BeamCode]),
- ?line ok = file:write_file_info(ArgsFile, OrigFI),
-
+ ?line ok = file:write_file_info(ArgsFile, OrigFI),
+
?line run(Dir, ArgsBase ++ " -arg1 arg2 arg3",
[<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n"
"nostick:[{nostick,[]}]\n"
@@ -356,13 +362,13 @@ archive_script(Config) when is_list(Config) ->
?line ok = compile_app(TopDir, "archive_script_dict"),
?line ok = compile_app(TopDir, "archive_script_dummy"),
?line {ok, MainFiles} = file:list_dir(TopDir),
- ?line ok = compile_files(MainFiles, TopDir, TopDir),
-
+ ?line ok = compile_files(MainFiles, TopDir, TopDir),
+
%% Create the archive
{ok, TopFiles} = file:list_dir(TopDir),
?line {ok, {_, ArchiveBin}} = zip:create(Archive, TopFiles,
[memory, {compress, []}, {cwd, TopDir}]),
-
+
%% Read the source script
OrigFile = filename:join([DataDir, "emulator_flags"]),
{ok, OrigBin} = file:read_file(OrigFile),
@@ -371,73 +377,73 @@ archive_script(Config) when is_list(Config) ->
Flags = "%%! -archive_script_dict foo bar"
" -archive_script_dict foo"
" -archive_script_dummy bar",
- ?line {ok, OrigFI} = file:read_file_info(OrigFile),
-
+ ?line {ok, OrigFI} = file:read_file_info(OrigFile),
+
%%%%%%%
%% Create and run scripts without emulator flags
- MainBase = "archive_script_main",
- MainScript = filename:join([PrivDir, MainBase]),
+ MainBase = "archive_script_main",
+ MainScript = filename:join([PrivDir, MainBase]),
%% With shebang
- ?line ok = file:write_file(MainScript,
+ ?line ok = file:write_file(MainScript,
[Shebang, "\n",
Flags, "\n",
ArchiveBin]),
- ?line ok = file:write_file_info(MainScript, OrigFI),
-
+ ?line ok = file:write_file_info(MainScript, OrigFI),
+
?line run(PrivDir, MainBase ++ " -arg1 arg2 arg3",
- [<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n"
+ [<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n"
"dict:[{archive_script_dict,[\"foo\",\"bar\"]},{archive_script_dict,[\"foo\"]}]\n"
"dummy:[{archive_script_dummy,[\"bar\"]}]\n"
"priv:{ok,<<\"Some private data...\\n\">>}\n"
"ExitCode:0">>]),
- ?line run(PrivDir, "", MainBase ++ " -arg1 arg2 arg3",
- [<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n"
+ ?line run_with_opts(PrivDir, "", MainBase ++ " -arg1 arg2 arg3",
+ [<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n"
"dict:[{archive_script_dict,[\"foo\",\"bar\"]},{archive_script_dict,[\"foo\"]}]\n"
"dummy:[{archive_script_dummy,[\"bar\"]}]\n"
"priv:{ok,<<\"Some private data...\\n\">>}\n"
"ExitCode:0">>]),
-
+
?line ok = file:rename(MainScript, MainScript ++ "_with_shebang"),
%% Without shebang (no flags)
- ?line ok = file:write_file(MainScript,
+ ?line ok = file:write_file(MainScript,
["Something else than shebang!!!", "\n",
ArchiveBin]),
- ?line ok = file:write_file_info(MainScript, OrigFI),
-
- ?line run(PrivDir, "", MainBase ++ " -arg1 arg2 arg3",
- [<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n"
+ ?line ok = file:write_file_info(MainScript, OrigFI),
+
+ ?line run_with_opts(PrivDir, "", MainBase ++ " -arg1 arg2 arg3",
+ [<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n"
"dict:[]\n"
"dummy:[]\n"
"priv:{ok,<<\"Some private data...\\n\">>}\n"
"ExitCode:0">>]),
?line ok = file:rename(MainScript, MainScript ++ "_without_shebang"),
-
+
%% Plain archive without header (no flags)
-
+
?line ok = file:write_file(MainScript, [ArchiveBin]),
- ?line ok = file:write_file_info(MainScript, OrigFI),
-
- ?line run(PrivDir, "", MainBase ++ " -arg1 arg2 arg3",
- [<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n"
+ ?line ok = file:write_file_info(MainScript, OrigFI),
+
+ ?line run_with_opts(PrivDir, "", MainBase ++ " -arg1 arg2 arg3",
+ [<<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n"
"dict:[]\n"
"dummy:[]\n"
"priv:{ok,<<\"Some private data...\\n\">>}\n"
"ExitCode:0">>]),
?line ok = file:rename(MainScript, MainScript ++ "_without_header"),
-
+
%%%%%%%
%% Create and run scripts with emulator flags
AltBase = "archive_script_alternate_main",
AltScript = filename:join([PrivDir, AltBase]),
- ?line ok = file:write_file(AltScript,
+ ?line ok = file:write_file(AltScript,
[Shebang, "\n",
Mode, "\n",
Flags, " -escript main archive_script_main2\n",
ArchiveBin]),
- ?line ok = file:write_file_info(AltScript, OrigFI),
+ ?line ok = file:write_file_info(AltScript, OrigFI),
?line run(PrivDir, AltBase ++ " -arg1 arg2 arg3",
[<<"main2:[\"-arg1\",\"arg2\",\"arg3\"]\n"
@@ -445,7 +451,7 @@ archive_script(Config) when is_list(Config) ->
"dummy:[{archive_script_dummy,[\"bar\"]}]\n"
"priv:{ok,<<\"Some private data...\\n\">>}\n"
"ExitCode:0">>]),
-
+
ok.
compile_app(TopDir, AppName) ->
@@ -482,6 +488,254 @@ epp(Config) when is_list(Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+create_and_extract(Config) when is_list(Config) ->
+ {NewFile, FileInfo,
+ EmuArg, Source,
+ _ErlBase, ErlCode,
+ _BeamBase, BeamCode,
+ ArchiveBin} =
+ prepare_creation("create_and_extract", Config),
+
+ Bodies =
+ [[{source, ErlCode}],
+ [{beam, BeamCode}],
+ [{archive, ArchiveBin}]],
+
+ %% Verify all combinations of scripts with shebangs
+ [verify_sections(NewFile, FileInfo, S ++ C ++ E ++ B) ||
+ S <- [[{shebang, default}],
+ [{shebang, "/usr/bin/env escript"}]],
+ C <- [[],
+ [{comment, undefined}],
+ [{comment, default}],
+ [{comment, "This is a nonsense comment"}]],
+ E <- [[],
+ [{emu_args, undefined}],
+ [{emu_args, EmuArg}]],
+ B <- [[{source, Source}] | Bodies]],
+
+ %% Verify all combinations of scripts without shebangs
+ [verify_sections(NewFile, FileInfo, S ++ C ++ E ++ B) ||
+ S <- [[], [{shebang, undefined}]],
+ C <- [[], [{comment, undefined}]],
+ E <- [[], [{emu_args, undefined}]],
+ B <- Bodies],
+
+ %% Verify the compile_source option
+ file:delete(NewFile),
+ ?line ok = escript:create(NewFile, [{source, Source}]),
+ ?line {ok, [_, _, _, {source, Source}]} = escript:extract(NewFile, []),
+ ?line {ok, [_, _, _, {source, BeamCode2}]} =
+ escript:extract(NewFile, [compile_source]),
+ verify_sections(NewFile, FileInfo,
+ [{shebang, default},
+ {comment, default},
+ {beam, BeamCode2}]),
+
+ file:delete(NewFile),
+ ok.
+
+prepare_creation(Base, Config) ->
+ %% Read the source
+ PrivDir = ?config(priv_dir, Config),
+ DataDir = ?config(data_dir, Config),
+ OrigFile = filename:join([DataDir,"emulator_flags"]),
+ ?line {ok, FileInfo} = file:read_file_info(OrigFile),
+ NewFile = filename:join([PrivDir, Base]),
+ ?line {ok, [{shebang, default},
+ {comment, _},
+ {emu_args, EmuArg},
+ {source, Source}]} =
+ escript:extract(OrigFile, []),
+
+ %% Compile the code
+ ErlFile = NewFile ++ ".erl",
+ ErlCode = list_to_binary(["\n-module(", Base, ").\n",
+ "-export([main/1]).\n\n",
+ Source, "\n\n"]),
+ ?line ok = file:write_file(ErlFile, ErlCode),
+
+ %% Compile the code
+ ?line {ok, _Mod, BeamCode} =
+ compile:file(ErlFile, [binary, debug_info]),
+
+ %% Create an archive
+ ?line {ok, {_, ArchiveBin}} =
+ zip:create("dummy_archive_name",
+ [{Base ++ ".erl", ErlCode},
+ {Base ++ ".beam", BeamCode}],
+ [{compress, []}, memory]),
+ {NewFile, FileInfo,
+ EmuArg, Source,
+ Base ++ ".erl", ErlCode,
+ Base ++ ".beam", BeamCode,
+ ArchiveBin}.
+
+verify_sections(File, FileInfo, Sections) ->
+ io:format("~p:verify_sections(\n\t~p,\n\t~p,\n\t~p).\n",
+ [?MODULE, File, FileInfo, Sections]),
+
+ %% Create
+ file:delete(File),
+ ?line ok = escript:create(File, Sections),
+ ?line ok = file:write_file_info(File, FileInfo),
+
+ %% Run
+ Dir = filename:absname(filename:dirname(File)),
+ Base = filename:basename(File),
+
+ HasArg = fun(Tag) ->
+ case lists:keysearch(Tag, 1, Sections) of
+ false -> false;
+ {value, {_, undefined}} -> false;
+ {value, _} -> true
+ end
+ end,
+ ExpectedMain = <<"main:[\"-arg1\",\"arg2\",\"arg3\"]\n">>,
+ ExpectedOutput =
+ case HasArg(emu_args) of
+ true ->
+ <<"nostick:[{nostick,[]}]\n"
+ "mnesia:[{mnesia,[\"dir\",\"a/directory\"]},{mnesia,[\"debug\",\"verbose\"]}]\n"
+ "ERL_FLAGS=false\n"
+ "unknown:[]\n"
+ "ExitCode:0">>;
+ false ->
+ <<"nostick:[]\nmnesia:[]\nERL_FLAGS=false\nunknown:[]\nExitCode:0">>
+ end,
+
+ InputArgs = Base ++ " -arg1 arg2 arg3",
+ Expected = <<ExpectedMain/binary, ExpectedOutput/binary>>,
+ case HasArg(shebang) of
+ true ->
+ ?line run(Dir, InputArgs, [Expected]);
+ false ->
+ ?line run_with_opts(Dir, [], InputArgs, [Expected])
+ end,
+
+ %% Verify
+ ?line {ok, Bin} = escript:create(binary, Sections),
+ ?line {ok, Read} = file:read_file(File),
+ ?line Bin = Read, % Assert
+
+ Normalized = normalize_sections(Sections),
+ ?line {ok, Extracted} = escript:extract(File, []),
+ io:format("Normalized; ~p\n", [Normalized]),
+ io:format("Extracted ; ~p\n", [Extracted]),
+ ?line Normalized = Extracted, % Assert
+ ok.
+
+normalize_sections(Sections) ->
+ AtomToTuple =
+ fun(Val) ->
+ if
+ is_atom(Val) -> {Val, default};
+ true -> Val
+ end
+ end,
+ case lists:map(AtomToTuple, [{K, V} || {K, V} <- Sections, V =/= undefined]) of
+ [{shebang, Shebang} | Rest] ->
+ [{shebang, Shebang} |
+ case Rest of
+ [{comment, Comment} | Rest2] ->
+ [{comment, Comment} |
+ case Rest2 of
+ [{emu_args, EmuArgs}, Body] ->
+ [{emu_args, EmuArgs}, Body];
+ [Body] ->
+ [{emu_args, undefined}, Body]
+ end
+ ];
+ [{emu_args, EmuArgs}, Body] ->
+ [{comment, undefined}, {emu_args, EmuArgs}, Body];
+ [Body] ->
+ [{comment, undefined}, {emu_args, undefined}, Body]
+ end
+ ];
+ [Body] ->
+ [{shebang, undefined}, {comment, undefined}, {emu_args, undefined}, Body]
+ end.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+foldl(Config) when is_list(Config) ->
+ {NewFile, _FileInfo,
+ _EmuArg, _Source,
+ ErlBase, ErlCode,
+ BeamBase, _BeamCode,
+ ArchiveBin} =
+ prepare_creation("foldl", Config),
+
+ Collect = fun(Name, GetInfo, GetBin, Acc) ->
+ [{Name, GetInfo(), GetBin()} | Acc]
+ end,
+
+ %% Get line numbers and the file attribute right
+ SourceFile = NewFile ++ ".erl",
+ <<_:1/binary, ErlCode2/binary>> = ErlCode,
+ ?line ok = file:write_file(SourceFile, ErlCode2),
+ ?line {ok, _Mod, BeamCode} =
+ compile:file(SourceFile, [binary, debug_info]),
+
+ %% Verify source script
+ ?line ok = escript:create(SourceFile, [{source, ErlCode}]),
+ ?line {ok, [{".", _, BeamCode2}]}
+ = escript_foldl(Collect, [], SourceFile),
+
+ ?line {ok, Abstr} = beam_lib:chunks(BeamCode, [abstract_code]),
+ ?line {ok, Abstr2} = beam_lib:chunks(BeamCode2, [abstract_code]),
+ %% io:format("abstr1=~p\n", [Abstr]),
+ %% io:format("abstr2=~p\n", [Abstr2]),
+ ?line Abstr = Abstr2, % Assert
+
+ %% Verify beam script
+ ?line ok = escript:create(NewFile, [{beam, BeamCode}]),
+ ?line {ok, [{".", _, BeamCode}]}
+ = escript_foldl(Collect, [], NewFile),
+
+ %% Verify archive scripts
+ ?line ok = escript:create(NewFile, [{archive, ArchiveBin}]),
+ ?line {ok, [{BeamBase, #file_info{}, _},
+ {ErlBase, #file_info{}, _}]}
+ = escript_foldl(Collect, [], NewFile),
+
+ ArchiveFiles = [{ErlBase, ErlCode}, {BeamBase, BeamCode}],
+ ?line ok = escript:create(NewFile, [{archive, ArchiveFiles, []}]),
+ ?line {ok, [{BeamBase, _, _},
+ {ErlBase, _, _}]}
+ = escript_foldl(Collect, [], NewFile),
+
+ ok.
+
+escript_foldl(Fun, Acc, File) ->
+ code:ensure_loaded(zip),
+ case erlang:function_exported(zip, foldl, 3) of
+ true ->
+ emulate_escript_foldl(Fun, Acc, File);
+ false ->
+ escript:foldl(Fun, Acc, File)
+ end.
+
+emulate_escript_foldl(Fun, Acc, File) ->
+ case escript:extract(File, [compile_source]) of
+ {ok, [_Shebang, _Comment, _EmuArgs, Body]} ->
+ case Body of
+ {source, BeamCode} ->
+ GetInfo = fun() -> file:read_file_info(File) end,
+ GetBin = fun() -> BeamCode end,
+ {ok, Fun(".", GetInfo, GetBin, Acc)};
+ {beam, BeamCode} ->
+ GetInfo = fun() -> file:read_file_info(File) end,
+ GetBin = fun() -> BeamCode end,
+ {ok, Fun(".", GetInfo, GetBin, Acc)};
+ {archive, ArchiveBin} ->
+ zip:foldl(Fun, Acc, {File, ArchiveBin})
+ end;
+ {error, Reason} ->
+ {error, Reason}
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
run(Dir, Cmd0, Expected0) ->
Expected = iolist_to_binary(expected_output(Expected0, Dir)),
Cmd = case os:type() of
@@ -490,7 +744,7 @@ run(Dir, Cmd0, Expected0) ->
end,
do_run(Dir, Cmd, Expected).
-run(Dir, Opts, Cmd0, Expected) ->
+run_with_opts(Dir, Opts, Cmd0, Expected) ->
Cmd = case os:type() of
{win32,_} -> "escript " ++ Opts ++ " " ++ filename:nativename(Dir) ++ "\\" ++ Cmd0;
_ -> "escript " ++ Opts ++ " " ++ Dir ++ "/" ++ Cmd0
@@ -533,8 +787,8 @@ expected_output([data_dir|T], Data) ->
[filename:nativename(Data)++Slash|expected_output(T, Data)];
expected_output([H|T], Data) ->
[H|expected_output(T, Data)];
-expected_output([], _) ->
+expected_output([], _) ->
[];
-expected_output(Bin, _) when is_binary(Bin) ->
+expected_output(Bin, _) when is_binary(Bin) ->
Bin.
diff --git a/lib/stdlib/test/zip_SUITE.erl b/lib/stdlib/test/zip_SUITE.erl
index 12ca655000..48b14396c1 100644
--- a/lib/stdlib/test/zip_SUITE.erl
+++ b/lib/stdlib/test/zip_SUITE.erl
@@ -18,12 +18,13 @@
%%
-module(zip_SUITE).
--export([all/1, borderline/1, atomic/1,
+-export([all/1, borderline/1, atomic/1,
bad_zip/1, unzip_from_binary/1, unzip_to_binary/1,
zip_to_binary/1,
unzip_options/1, zip_options/1, list_dir_options/1, aliases/1,
openzip_api/1, zip_api/1, unzip_jar/1,
- compress_control/1]).
+ compress_control/1,
+ foldl/1]).
-include("test_server.hrl").
-include("test_server_line.hrl").
@@ -35,7 +36,8 @@ all(suite) -> [borderline, atomic, bad_zip,
zip_to_binary,
unzip_options, zip_options, list_dir_options, aliases,
openzip_api, zip_api, unzip_jar,
- compress_control].
+ compress_control,
+ foldl].
borderline(doc) ->
["Test creating, listing and extracting one file from an archive "
@@ -110,17 +112,17 @@ get_data(Port, Expect) ->
{Port, {data, Bytes}} ->
get_data(Port, match_output(Bytes, Expect, Port));
{Port, eof} ->
- Port ! {self(), close},
+ Port ! {self(), close},
receive
{Port, closed} ->
true
- end,
+ end,
receive
- {'EXIT', Port, _} ->
+ {'EXIT', Port, _} ->
ok
after 1 -> % force context switch
ok
- end,
+ end,
match_output(eof, Expect, Port)
end.
@@ -290,7 +292,7 @@ unzip_options(Config) when is_list(Config) ->
DataDir = ?config(data_dir, Config),
PrivDir = ?config(priv_dir, Config),
Long = filename:join(DataDir, "abc.zip"),
-
+
%% create a temp directory
Subdir = filename:join(PrivDir, "t"),
ok = file:make_dir(Subdir),
@@ -303,7 +305,7 @@ unzip_options(Config) when is_list(Config) ->
%% Verify.
?line true = (length(FList) =:= length(RetList)),
- ?line lists:foreach(fun(F)-> {ok,B} = file:read_file(filename:join(DataDir, F)),
+ ?line lists:foreach(fun(F)-> {ok,B} = file:read_file(filename:join(DataDir, F)),
{ok,B} = file:read_file(filename:join(Subdir, F)) end,
FList),
?line lists:foreach(fun(F)-> ok = file:delete(F) end,
@@ -321,7 +323,7 @@ unzip_jar(Config) when is_list(Config) ->
DataDir = ?config(data_dir, Config),
PrivDir = ?config(priv_dir, Config),
JarFile = filename:join(DataDir, "test.jar"),
-
+
%% create a temp directory
Subdir = filename:join(PrivDir, "jartest"),
ok = file:make_dir(Subdir),
@@ -479,7 +481,7 @@ unzip_to_binary(Config) when is_list(Config) ->
DataDir = ?config(data_dir, Config),
PrivDir = ?config(priv_dir, Config),
- delete_all_in(PrivDir),
+ delete_all_in(PrivDir),
file:set_cwd(PrivDir),
Long = filename:join(DataDir, "abc.zip"),
@@ -595,17 +597,17 @@ do_delete_files([],Cnt) ->
Cnt;
do_delete_files([Item|Rest], Cnt) ->
case file:delete(Item) of
- ok ->
+ ok ->
DelCnt = 1;
{error,eperm} ->
file:change_mode(Item, 8#777),
DelCnt = delete_files(filelib:wildcard(filename:join(Item, "*"))),
- file:del_dir(Item);
+ file:del_dir(Item);
{error,eacces} ->
%% We'll see about that!
file:change_mode(Item, 8#777),
case file:delete(Item) of
- ok ->
+ ok ->
DelCnt = 1;
{error,_} ->
erlang:yield(),
@@ -643,22 +645,22 @@ compress_control(Config) when is_list(Config) ->
],
test_compress_control(Dir,
- Files,
+ Files,
[{compress, []}],
[]),
test_compress_control(Dir,
- Files,
+ Files,
[{uncompress, all}],
[]),
test_compress_control(Dir,
- Files,
+ Files,
[{uncompress, []}],
[".txt", ".exe", ".zip", ".lzh", ".arj"]),
test_compress_control(Dir,
- Files,
+ Files,
[],
[".txt", ".exe"]),
@@ -686,7 +688,7 @@ test_compress_control(Dir, Files, ZipOptions, Expected) ->
create_files(Files),
{ok, Zip} = zip:create(Zip, [Dir], ZipOptions),
-
+
{ok, OpenZip} = zip:openzip_open(Zip, [memory]),
{ok,[#zip_comment{comment = ""} | ZipList]} = zip:openzip_list_dir(OpenZip),
io:format("compress_control: -> ~p -> ~p\n -> ~pn", [Expected, ZipOptions, ZipList]),
@@ -698,19 +700,19 @@ test_compress_control(Dir, Files, ZipOptions, Expected) ->
delete_files(lists:reverse(Names)), % Remove plain files before directories
ok.
-
+
verify_compression([{Name, Kind, _Filler} | Files], ZipList, OpenZip, ZipOptions, Expected) ->
{Name2, BinSz} =
case Kind of
- dir ->
+ dir ->
{Name ++ "/", 0};
- _ ->
+ _ ->
{ok, {Name, Bin}} = zip:openzip_get(Name, OpenZip),
{Name, size(Bin)}
end,
{Name2, {value, ZipFile}} = {Name2, lists:keysearch(Name2, #zip_file.name, ZipList)},
#zip_file{info = #file_info{size = InfoSz, type = InfoType}, comp_size = InfoCompSz} = ZipFile,
-
+
Ext = filename:extension(Name),
IsComp = is_compressed(Ext, Kind, ZipOptions),
ExpComp = lists:member(Ext, Expected),
@@ -757,3 +759,33 @@ extensions([H | T], Old) ->
extensions([], Old) ->
Old.
+foldl(Config) ->
+ PrivDir = ?config(priv_dir, Config),
+ File = filename:join([PrivDir, "foldl.zip"]),
+
+ FooBin = <<"FOO">>,
+ BarBin = <<"BAR">>,
+ Files = [{"foo", FooBin}, {"bar", BarBin}],
+ ?line {ok, {File, Bin}} = zip:create(File, Files, [memory]),
+ ZipFun = fun(N, I, B, Acc) -> [{N, B(), I()} | Acc] end,
+ ?line {ok, FileSpec} = zip:foldl(ZipFun, [], {File, Bin}),
+ ?line [{"bar", BarBin, #file_info{}}, {"foo", FooBin, #file_info{}}] = FileSpec,
+ ?line {ok, {File, Bin}} = zip:create(File, lists:reverse(FileSpec), [memory]),
+ ?line {foo_bin, FooBin} =
+ try
+ zip:foldl(fun("foo", _, B, _) -> throw(B()); (_, _, _, Acc) -> Acc end, [], {File, Bin})
+ catch
+ throw:FooBin ->
+ {foo_bin, FooBin}
+ end,
+ ?line ok = file:write_file(File, Bin),
+ ?line {ok, FileSpec} = zip:foldl(ZipFun, [], File),
+
+ ?line {error, einval} = zip:foldl(fun() -> ok end, [], File),
+ ?line {error, einval} = zip:foldl(ZipFun, [], 42),
+ ?line {error, einval} = zip:foldl(ZipFun, [], {File, 42}),
+
+ ?line ok = file:delete(File),
+ ?line {error, enoent} = zip:foldl(ZipFun, [], File),
+
+ ok.
diff --git a/lib/test_server/doc/src/test_server_ctrl.xml b/lib/test_server/doc/src/test_server_ctrl.xml
index 0ed5f88544..4a778bcaf7 100644
--- a/lib/test_server/doc/src/test_server_ctrl.xml
+++ b/lib/test_server/doc/src/test_server_ctrl.xml
@@ -610,7 +610,7 @@ Optional, if not given the test server controller node
<tag><c>NAME name</c></tag>
<item>Names the test suite to something else than the
default name. This does not apply to <c>SPEC</c> which keeps
- it's names.
+ its names.
</item>
<tag><c>PARAMETERS parameterfile</c></tag>
<item>Specifies the parameter file to use when starting
diff --git a/lib/tools/emacs/test.erl.indented b/lib/tools/emacs/test.erl.indented
index faf1cc68ef..d0ea4c29cf 100644
--- a/lib/tools/emacs/test.erl.indented
+++ b/lib/tools/emacs/test.erl.indented
@@ -1,20 +1,20 @@
%% -*- erlang -*-
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%%-------------------------------------------------------------------
diff --git a/lib/tools/emacs/test.erl.orig b/lib/tools/emacs/test.erl.orig
index 764566005a..70e97a2e91 100644
--- a/lib/tools/emacs/test.erl.orig
+++ b/lib/tools/emacs/test.erl.orig
@@ -1,20 +1,20 @@
%% -*- erlang -*-
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2009-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%%-------------------------------------------------------------------
diff --git a/lib/wx/c_src/wxe_driver.c b/lib/wx/c_src/wxe_driver.c
index 3b951bec57..310325ea26 100644
--- a/lib/wx/c_src/wxe_driver.c
+++ b/lib/wx/c_src/wxe_driver.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2008-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2008-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -113,6 +113,7 @@ wxe_driver_start(ErlDrvPort port, char *buff)
data->driver_data = NULL;
data->bin = NULL;
data->port = port;
+ data->pdl = driver_pdl_create(port);
if(WXE_DRV_PORT == 0) {
for(; *buff != 32; buff++);
buff++;
@@ -124,7 +125,7 @@ wxe_driver_start(ErlDrvPort port, char *buff)
if(!(start_native_gui(data) == 1))
return(ERL_DRV_ERROR_GENERAL); /* ENOMEM */
} else {
- meta_command(CREATE_PORT,data);
+ meta_command(CREATE_PORT,data);
}
return (ErlDrvData) data;
}
diff --git a/lib/wx/c_src/wxe_driver.h b/lib/wx/c_src/wxe_driver.h
index 8437b4eb36..13a17e356f 100644
--- a/lib/wx/c_src/wxe_driver.h
+++ b/lib/wx/c_src/wxe_driver.h
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2008-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2008-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -45,6 +45,7 @@ typedef struct wxe_data_def {
WXEBinRef * bin; /* Argument binaries */
ErlDrvPort port;
int is_cbport;
+ ErlDrvPDL pdl;
} wxe_data;
diff --git a/lib/wx/c_src/wxe_impl.cpp b/lib/wx/c_src/wxe_impl.cpp
index 4486dff63b..528a08e654 100644
--- a/lib/wx/c_src/wxe_impl.cpp
+++ b/lib/wx/c_src/wxe_impl.cpp
@@ -101,7 +101,7 @@ int start_native_gui(wxe_data *sd)
init_caller = driver_connected(sd->port);
if((res = erl_drv_thread_create((char *)"wxwidgets",
- &wxe_thread,wxe_main_loop,NULL,NULL)) == 0) {
+ &wxe_thread,wxe_main_loop,(void *) sd->pdl,NULL)) == 0) {
erl_drv_mutex_lock(wxe_status_m);
for(;wxe_status == WXE_NOT_INITIATED;) {
erl_drv_cond_wait(wxe_status_c, wxe_status_m);
@@ -179,12 +179,15 @@ void meta_command(int what, wxe_data *sd) {
* wxWidgets Thread
* ************************************************************/
-void *wxe_main_loop(void * not_used)
+void *wxe_main_loop(void *vpdl)
{
int result;
int argc = 1;
char * temp = (char *) "Erlang\0";
char ** argv = &temp;
+ ErlDrvPDL pdl = (ErlDrvPDL) vpdl;
+
+ driver_pdl_inc_refc(pdl);
// ErlDrvSysInfo einfo;
// driver_system_info(&einfo, sizeof(ErlDrvSysInfo));
@@ -199,6 +202,7 @@ void *wxe_main_loop(void * not_used)
if(result >= 0 && wxe_status == WXE_INITIATED) {
/* We are done try to make a clean exit */
wxe_status = WXE_EXITED;
+ driver_pdl_dec_refc(pdl);
erl_drv_thread_exit(NULL);
return NULL;
} else {
@@ -206,6 +210,7 @@ void *wxe_main_loop(void * not_used)
wxe_status = WXE_ERROR;
erl_drv_cond_signal(wxe_status_c);
erl_drv_mutex_unlock(wxe_status_m);
+ driver_pdl_dec_refc(pdl);
return NULL;
}
}
@@ -401,11 +406,12 @@ void WxeApp::dispatch_cb(wxList * batch, wxList * temp, ErlDrvTermData process)
node = batch->GetFirst())
{
wxeCommand *event = (wxeCommand *)node->GetData();
+ wxeMemEnv *memenv = getMemEnv(event->port);
batch->Erase(node);
if(event->caller == process || // Callbacks from CB process only
event->op == WXE_CB_START || // Recursive event callback allow
// Allow connect_cb during CB i.e. msg from wxe_server.
- event->caller == driver_connected(event->port))
+ event->caller == memenv->owner)
{
switch(event->op) {
case WXE_BATCH_END:
@@ -456,6 +462,9 @@ void WxeApp::dispatch_cb(wxList * batch, wxList * temp, ErlDrvTermData process)
void WxeApp::newMemEnv(wxeMetaCommand& Ecmd) {
wxeMemEnv * memenv = new wxeMemEnv();
+
+ driver_pdl_inc_refc(Ecmd.pdl);
+
for(int i = 0; i < global_me->next; i++) {
memenv->ref2ptr[i] = global_me->ref2ptr[i];
}
@@ -576,6 +585,7 @@ void WxeApp::destroyMemEnv(wxeMetaCommand& Ecmd) {
// }
// fflush(stderr);
delete memenv;
+ driver_pdl_dec_refc(Ecmd.pdl);
refmap.erase((ErlDrvTermData) Ecmd.port);
}
diff --git a/lib/wx/c_src/wxe_impl.h b/lib/wx/c_src/wxe_impl.h
index 5e9d596633..39c02f8c1a 100644
--- a/lib/wx/c_src/wxe_impl.h
+++ b/lib/wx/c_src/wxe_impl.h
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2008-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2008-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -34,15 +34,16 @@ class wxeMetaCommand : public wxEvent
public:
wxeMetaCommand(wxe_data *sd, int EvId)
: wxEvent(EvId, wxeEVT_META_COMMAND)
- { caller = driver_caller(sd->port); port = sd->port; } ;
+ { caller = driver_caller(sd->port); port = sd->port; pdl = sd->pdl; } ;
wxeMetaCommand(const wxeMetaCommand& event)
: wxEvent(event)
- { caller = event.caller; port = event.port; };
+ { caller = event.caller; port = event.port; pdl = event.pdl; };
virtual ~wxeMetaCommand() {};
virtual wxEvent *Clone() const { return new wxeMetaCommand(*this); }
ErlDrvTermData caller;
ErlDrvPort port;
+ ErlDrvPDL pdl;
};
class wxeCommand : public wxObject
diff --git a/lib/xmerl/doc/src/notes.xml b/lib/xmerl/doc/src/notes.xml
index 0f30ae9eca..3106c72bd8 100644
--- a/lib/xmerl/doc/src/notes.xml
+++ b/lib/xmerl/doc/src/notes.xml
@@ -54,7 +54,7 @@
<item>
<p>
A continuation clause of <c>parse_reference/3</c> had
- it's parameters in wrong order.</p>
+ its parameters in wrong order.</p>
<p>
Own Id: OTP-8251 Aux Id: seq11429 </p>
</item>
diff --git a/make/emd2exml.in b/make/emd2exml.in
new file mode 100644
index 0000000000..17cb0a0b57
--- /dev/null
+++ b/make/emd2exml.in
@@ -0,0 +1,1285 @@
+#!/usr/bin/env escript
+%% -*- erlang -*-
+%%! -smp disable
+
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%%-------------------------------------------------------------------
+%%% File : emd2exml.in
+%%% Author : Rickard Green
+%%% Description : Erlangish MarkDown To Erlangish XML
+%%%
+%%% Note that this script has *one and only one*
+%%% specific purpose. That purpose is to generate XML
+%%% that fits into the Erlang/OTP documentation, so that
+%%% the Erlang/OTP "readme" files also can be part of
+%%% the Erlang/OTP HTML and Erlang/OTP PDF
+%%% documentation. Nothing more, nothing less. It is
+%%% *not* intended as some kind of a generic Markdown to
+%%% XML tool, and never will be.
+%%%
+%%% Created : 25 Feb 2010 by Rickard Green
+%%%-------------------------------------------------------------------
+
+-define(MAX_HEADING, 3).
+
+-define(DELAYED_COPYRIGHT_IX, 0).
+-define(DELAYED_TOC_IX, 1).
+-define(DELAYED_START_IX, 2).
+
+-mode(compile).
+
+-export([main/1]).
+
+-record(state,{h = 0,
+ p = false,
+ c = no,
+ note = false,
+ warning = false,
+ emphasis = no,
+ code = false,
+ code_blank = [],
+ bq_lvl = 0,
+ mlist = [],
+ list_p = false,
+ list_type_stack = [],
+ list_p_stack = [],
+ list_lvl = 0,
+ line_no = -1,
+ line = "",
+ type = blank,
+ bq_type = 0,
+ prev_line = "",
+ prev_type = blank,
+ next_line = "",
+ next_type = blank,
+ bq_next_type = 0,
+ delayed_array,
+ delayed_array_ix = ?DELAYED_START_IX,
+ delayed_tree,
+ out = [],
+ copyright = false,
+ copyright_data = [],
+ have_h1 = false,
+ smarker_ix = false,
+ toc = [],
+ ifile,
+ ofile}).
+
+main([I, O]) ->
+ IFD = file_ropen(I),
+ S0 = get_line(get_line(#state{ifile = IFD,
+ ofile = {O, undefined},
+ delayed_array = array:new(),
+ delayed_tree = gb_trees:empty()})),
+ S1 = complete_output(parse(S0)),
+ file_close(IFD),
+ OFD = file_wopen(O),
+ write_output(OFD, S1#state.out),
+ file_close(OFD),
+ stop();
+main(_) ->
+ io:format(standard_error,
+ "Usage: emd2exml <Input Markdown File> <Output XML file>~n",[]),
+ stop(1).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% Parser
+%%
+
+%%
+%% Eof
+%%
+
+parse(#state{h = H, line = eof} = S) ->
+ sections(0, H, end_all(S));
+
+%%
+%% Note
+%%
+
+parse(#state{line = "> *NOTE*: " ++ Line,
+ note = false,
+ type = {bquote, 0, 1}} = S0) ->
+ S1 = put_line(end_all(S0#state{note = true, bq_lvl = 1}), "<note>"),
+ parse(S1#state{line = Line, type = type(Line), bq_type = 1});
+
+parse(#state{bq_lvl = 1, note = true, bq_type = 0} = S) ->
+ parse(put_line(end_all(S#state{bq_lvl = 0, note = false}), "</note>"));
+
+%%
+%% Warning
+%%
+
+parse(#state{line = "> *WARNING*: " ++ Line,
+ warning = false,
+ type = {bquote, 0, 1}} = S0) ->
+ S1 = put_line(end_all(S0#state{warning = true, bq_lvl = 1}), "<warning>"),
+ parse(S1#state{line = Line, type = type(Line), bq_type = 1});
+
+parse(#state{bq_lvl = 1, warning = true, bq_type = 0} = S) ->
+ parse(put_line(end_all(S#state{bq_lvl = 0, warning = false}), "</warning>"));
+
+%%
+%% Block quote
+%%
+
+parse(#state{note = false,
+ warning = false,
+ line = BQLine,
+ type = {bquote, TxtLvl, BQLvl}} = S0) ->
+ Line = rm_bquote(TxtLvl, BQLvl, BQLine),
+ S1 = chg_bq_lvl(BQLvl, S0),
+ parse(S1#state{line = Line, type = type(Line), bq_type = BQLvl});
+
+% This clause is also used by warning and note
+parse(#state{bq_lvl = BQLvl,
+ next_line = BQLine,
+ next_type = {bquote, TxtLvl, BQLvl}} = S) ->
+ Line = rm_bquote(TxtLvl, BQLvl, BQLine),
+ parse(S#state{next_line = Line,
+ next_type = type(Line),
+ bq_next_type = BQLvl});
+
+parse(#state{note = false,
+ warning = false,
+ bq_lvl = Lvl, bq_type = 0} = S) when Lvl /= 0->
+ parse(chg_bq_lvl(0, S));
+
+%%
+%% Multiple blank lines
+%%
+
+% Keep multiple blank lines in code otherwise get rid of them...
+parse(#state{code = false, type = blank, next_type = blank} = S) ->
+ parse(get_line(S));
+
+%%
+%% Heading
+%%
+
+parse(#state{type = {text, 0}, next_type = {marker, h1}} = S) ->
+ parse(get_line(get_line(setext_heading(1, end_all(S)))));
+parse(#state{type = {text, 0}, next_type = {marker, h2}} = S) ->
+ parse(get_line(get_line(setext_heading(2, end_all(S)))));
+parse(#state{line = "#" ++ _} = S) ->
+ parse(get_line(atx_heading(end_all(S))));
+
+%%
+%% List
+%%
+
+parse(#state{code = false,
+ list_lvl = Lvl,
+ type = blank,
+ next_type = {text, 0}} = S) when Lvl /= 0 ->
+ parse(get_line(chg_list_lvl(S, 0)));
+
+parse(#state{code = false,
+ list_lvl = Lvl,
+ type = blank,
+ next_type = {text, TxtLvl}} = S) when Lvl /= 0,
+ TxtLvl >= Lvl ->
+ parse(get_line(put_line(list_use_p(S, yes), "")));
+
+parse(#state{code = false,
+ list_lvl = Lvl,
+ type = blank,
+ next_type = {uolist, ListLvl}} = S) when Lvl /= 0,
+ ListLvl >= Lvl-1 ->
+ parse(get_line(put_line(list_use_p(S, yes), "")));
+
+parse(#state{code = false,
+ list_lvl = Lvl,
+ type = blank,
+ next_type = {olist, ListLvl}} = S) when Lvl /= 0,
+ ListLvl >= Lvl-1 ->
+ parse(get_line(put_line(list_use_p(S, yes), "")));
+
+parse(#state{code = false,
+ type = {ListType, ListLvl},
+ line = Line} = S0) when ListType == uolist; ListType == olist ->
+ S1 = list_item(end_p(S0), ListType, ListLvl),
+ S2 = list_chk_nxt_line(put_text(put_list_p(S1, start),
+ list_strip(ListType, Line))),
+ parse(get_line(S2));
+
+parse(#state{code = false,
+ list_lvl = Lvl,
+ list_p = true,
+ type = {text, _},
+ line = Line} = S0) when Lvl /= 0 ->
+ S1 = list_chk_nxt_line(put_text(S0, list_strip(Line))),
+ parse(get_line(S1));
+
+parse(#state{code = false,
+ list_lvl = Lvl,
+ list_p = false,
+ type = {text, NewLvl},
+ line = Line} = S0) when Lvl /= 0, NewLvl < Lvl ->
+ S1 = chg_list_lvl(S0, NewLvl),
+ S2 = list_chk_nxt_line(put_text(put_list_p(S1, start), list_strip(Line))),
+ parse(get_line(S2));
+
+parse(#state{code = false,
+ list_lvl = Lvl,
+ list_p = false,
+ type = {text, Lvl},
+ line = Line} = S0) when Lvl /= 0 ->
+ S1 = list_chk_nxt_line(put_text(put_list_p(S0, start), list_strip(Line))),
+ parse(get_line(S1));
+
+%%
+%% Code
+%%
+
+parse(#state{code = false,
+ list_lvl = Lvl,
+ p = false,
+ prev_type = blank,
+ type = {text, TxtLvl},
+ line = Line} = S) when TxtLvl > Lvl ->
+ Data = code(strip_lvls(Lvl+1, Line)),
+ parse(get_line(put_chars(S#state{code = true},
+ ["<code type=\"none\">", nl(), Data])));
+parse(#state{code = true, type = blank, line = CB, code_blank = CBs} = S) ->
+ parse(get_line(S#state{code_blank = [CB | CBs]}));
+parse(#state{code = true,
+ code_blank = CB,
+ list_lvl = Lvl,
+ type = {text, TxtLvl},
+ line = Line} = S) when TxtLvl > Lvl ->
+ Data = code(strip_lvls(Lvl+1, Line)),
+ parse(get_line(put_chars(S#state{code_blank = []},
+ [strip_code_blank(Lvl+1, CB), Data])));
+parse(#state{code = true,
+ prev_type = blank,
+ type = {text, 0}} = S) ->
+ parse(chg_list_lvl(end_code(S), 0));
+parse(#state{code = true} = S) ->
+ parse(end_code(S));
+
+%%
+%% Paragraph
+%%
+
+parse(#state{p = false,
+ prev_type = blank,
+ type = {text, 0},
+ next_type = blank,
+ line = Line} = S) ->
+ parse(get_line(put_line(put_text(put_line(S, "<p>"), Line), "</p>")));
+parse(#state{p = false,
+ prev_type = blank,
+ type = {text, 0},
+ line = Line} = S) ->
+ parse(get_line(put_text(put_line(S#state{p = true}, "<p>"), Line)));
+parse(#state{p = true,
+ type = {text, 0},
+ next_type = blank,
+ line = Line} = S) ->
+ parse(get_line(put_line(put_text(S#state{p = false}, Line), "</p>")));
+
+%%
+%% Resolve link
+%%
+
+parse(#state{type = resolve_link} = S) ->
+ parse(get_line(resolve_link(S)));
+
+%%
+%% Plain text
+%%
+
+parse(#state{line = Line} = S) ->
+ parse(get_line(put_text(S, Line))).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% Auxilary functions
+%%%
+
+%%
+%% Text
+%%
+
+end_p(#state{p = false} = S) ->
+ S;
+end_p(#state{p = true} = S) ->
+ put_line(S#state{p = false}, "</p>").
+
+text(Line) ->
+ text(Line, []).
+
+text("%ERTS-VSN%" ++ Cs, Acc) ->
+ text(Cs, ["@ERTS_VSN@"|Acc]);
+text("%OTP-REL%" ++ Cs, Acc) ->
+ text(Cs, ["@OTP_REL@"|Acc]);
+
+text([$\\,C|Cs], Acc) ->
+ text(Cs, [C|Acc]);
+text([$<|Cs], Acc) ->
+ text(Cs, ["&lt;"|Acc]);
+text([$>|Cs], Acc) ->
+ text(Cs, ["&gt;"|Acc]);
+text([$&|Cs], Acc) ->
+ text(Cs, ["&amp;"|Acc]);
+text([$'|Cs], Acc) ->
+ text(Cs, ["&apos;"|Acc]);
+text([C|Cs], Acc) ->
+ text(Cs, [C|Acc]);
+text([], Acc) ->
+ lists:reverse(Acc).
+
+put_text(#state{c = CTag, emphasis = EmTag} = S, Line) ->
+ put_text(S, Line, CTag, EmTag, []).
+
+put_text(S, "%ERTS-VSN%"++Cs, CTag, EmTag, Acc) ->
+ put_text(S, Cs, CTag, EmTag, ["@ERTS_VSN@"|Acc]);
+put_text(S, "%OTP-REL%"++Cs, CTag, EmTag, Acc) ->
+ put_text(S, Cs, CTag, EmTag, ["@OTP_REL@"|Acc]);
+
+put_text(S, [$\\,C|Cs], no, EmTag, Acc) ->
+ put_text(S, Cs, no, EmTag, [C|Acc]);
+put_text(S, [C,C|Cs], no, b, Acc) when C == $*; C == $_ ->
+ put_text(S, Cs, no, no, ["</b>"|Acc]);
+put_text(S, [C,C|Cs], no, no, Acc) when C == $*; C == $_ ->
+ put_text(S, Cs, no, b, ["<b>"|Acc]);
+put_text(S, [C|Cs], no, em, Acc) when C == $*; C == $_ ->
+ put_text(S, Cs, no, no, ["</em>"|Acc]);
+put_text(S, [C|Cs], no, no, Acc) when C == $*; C == $_ ->
+ put_text(S, Cs, no, em, ["<em>"|Acc]);
+put_text(S, [$`,$`|Cs], double, EmTag, Acc) ->
+ put_text(S, Cs, no, EmTag, ["</c>"|Acc]);
+put_text(S, [$`,$`|Cs], no, EmTag, Acc) ->
+ put_text(S, Cs, double, EmTag, ["<c>"|Acc]);
+put_text(S, [$`|Cs], single, EmTag, Acc) ->
+ put_text(S, Cs, no, EmTag, ["</c>"|Acc]);
+put_text(S, [$`|Cs], no, EmTag, Acc) ->
+ put_text(S, Cs, single, EmTag, ["<c>"|Acc]);
+put_text(S, [$<|Cs], CTag, EmTag, Acc) when CTag /= no ->
+ put_text(S, Cs, CTag, EmTag, ["&lt;"|Acc]);
+put_text(S, [$>|Cs], CTag, EmTag, Acc) when CTag /= no ->
+ put_text(S, Cs, CTag, EmTag, ["&gt;"|Acc]);
+put_text(S, [$&|Cs], CTag, EmTag, Acc) when CTag /= no ->
+ put_text(S, Cs, CTag, EmTag, ["&amp;"|Acc]);
+put_text(S, [$'|Cs], CTag, EmTag, Acc)when CTag /= no ->
+ put_text(S, Cs, CTag, EmTag, ["&apos;"|Acc]);
+put_text(S, [$<|Cs], no, EmTag, Acc) ->
+ case auto_link(Cs) of
+ no -> put_text(S, Cs, no, EmTag, [$<|Acc]);
+ {URL, NewCs} -> put_text(S, NewCs, no, EmTag, [URL|Acc])
+ end;
+put_text(S0, "![" ++ Cs, no, EmTag, Acc) ->
+ put_text_link_or_image(S0, image, "![", Cs, EmTag, Acc);
+put_text(S0, [$[|Cs], no, EmTag, Acc) ->
+ put_text_link_or_image(S0, link, $[, Cs, EmTag, Acc);
+put_text(S, " \n", CTag, EmTag, Acc) ->
+ put_text(S, [], CTag, EmTag, ["<br/>\n"|Acc]);
+put_text(S, " \r", CTag, EmTag, Acc) ->
+ put_text(S, [], CTag, EmTag, ["<br/>\r"|Acc]);
+put_text(S, " \r\n", CTag, EmTag, Acc) ->
+ put_text(S, [], CTag, EmTag, ["<br/>\r\n"|Acc]);
+put_text(S, [C|Cs], CTag, EmTag, Acc) ->
+ put_text(S, Cs, CTag, EmTag, [C|Acc]);
+put_text(S0, [], CTag, EmTag, Acc) ->
+ S1 = put_chars(S0, [lists:reverse(Acc)]),
+ S1#state{c = CTag, emphasis = EmTag}.
+
+put_text_link_or_image(S0, Type, Head, Tail0, EmTag, Acc) ->
+ case link_or_image(Tail0, Type) of
+ no -> put_text(S0, Tail0, no, EmTag, [Head|Acc]);
+ {LnkOrImg, Tail1} -> put_text(S0, Tail1, no, EmTag, [LnkOrImg|Acc]);
+ {delayed, Type, Key, Text, Tail1} ->
+ chk_key(Type, Key, S0),
+ S1 = put_chars(S0, [lists:reverse(Acc)]),
+ S2 = put_delayed(S1, Key, {Type, Text, S1#state.line_no}),
+ put_text(S2, Tail1, no, EmTag, [])
+ end.
+
+%%
+%% Links
+%%
+
+chk_key(Type, [$?|_] = Key, #state{ifile = {File, _}, line_no = Line}) ->
+ error(File, Line, "~s definition name `~ts' begin with a `?' character",
+ [case Type of
+ image -> "Image";
+ _ -> "Link"
+ end,
+ Key]);
+chk_key(_, _, _) ->
+ ok.
+
+auto_link(Str) ->
+ case url(Str) of
+ no -> no;
+ Res -> Res
+ end.
+
+url(Str) ->
+ url(Str, false, []).
+
+url([$\\,C|Cs], Bool, Acc) ->
+ url(Cs, Bool, [C|Acc]);
+url([$>|_Cs], false, _Acc) ->
+ no;
+url([$>|Cs], true, Acc) ->
+ Url = text(lists:reverse(Acc)),
+ {["<url href=\"", Url, "\">", Url, "</url>"], Cs};
+url("://" ++ _Cs, true, _Acc) ->
+ no;
+url("://" ++ Cs, false, Acc) ->
+ url(Cs, true, [$/,$/,$:|Acc]);
+url([C|Cs], Bool, Acc) ->
+ url(Cs, Bool, [C|Acc]).
+
+link_or_image(Str, Type) ->
+ case link_or_image_text(Str, "") of
+ no -> no;
+ {Text, Cont1} ->
+ case link_or_image_data(Cont1, none, Type, "", "") of
+ no -> no;
+ {url, Url, _Title, Cont2} ->
+ {["<url href=\"", text(Url), "\">", text(Text), "</url>"],
+ Cont2};
+ {seealso, SeeAlso, _Title, Cont2} ->
+ {["<seealso marker=\"", text(SeeAlso), "\">",
+ text(Text), "</seealso>"],
+ Cont2};
+ {image, Image, Title, Cont2} ->
+ {["<image file=\"", text(Image), "\"><icaption>",
+ text(Title), "</icaption></image>"],
+ Cont2};
+ {delayed, text, Cont2} ->
+ {delayed, Type, Text, Text, Cont2};
+ {delayed, Key, Cont2} ->
+ {delayed, Type, Key, Text, Cont2}
+ end
+ end.
+
+link_or_image_text([$\\,C|Cs], Acc) ->
+ link_or_image_text(Cs, [C|Acc]);
+link_or_image_text([$]|_Cs], "") ->
+ no;
+link_or_image_text([$]|Cs], Acc) ->
+ {lists:reverse(Acc), Cs};
+link_or_image_text([C|Cs], Acc) ->
+ link_or_image_text(Cs, [C|Acc]);
+link_or_image_text([], _Acc) ->
+ no.
+
+link_or_image_data([C|Cs], none, link, "", "") when C == $ ; C == $\t ->
+ link_or_image_data(Cs, none, link, "", "");
+link_or_image_data([C|Cs], none, image, "", "") when C == $ ; C == $\t ->
+ link_or_image_data(Cs, none, image, "", "");
+
+link_or_image_data([$\\,C|Cs], How, Type, Eltit, Lru) when How /= none ->
+ link_or_image_data(Cs, How, Type, Eltit, [C|Lru]);
+
+link_or_image_data([$(|Cs], none, link, "", "") ->
+ link_or_image_data(Cs, {inline, read}, seealso, "", "");
+link_or_image_data([$(|Cs], none, image, "", "") ->
+ link_or_image_data(Cs, {inline, read}, image, "", "");
+link_or_image_data([$)|_Cs], {inline, _}, _Type, "", "") ->
+ no;
+link_or_image_data([$)|Cs], {inline, _}, Type, Eltit, Lru) ->
+ {Type, lists:reverse(ws_strip(Lru)), lists:reverse(ws_strip(Eltit)), Cs};
+link_or_image_data("://" ++Cs, {inline, read} = IR, seealso, Eltit, Lru) ->
+ link_or_image_data(Cs, IR, url, Eltit, [$/,$/,$:|Lru]);
+link_or_image_data([$"|Cs], {inline, read}, Type, "", Lru) ->
+ link_or_image_data(Cs, {inline, read_title}, Type, "", Lru);
+link_or_image_data([$"|Cs], {inline, read_title}, Type, Eltit, Lru) ->
+ link_or_image_data(Cs, {inline, drop}, Type, Eltit, Lru);
+link_or_image_data([C|Cs], {inline, read} = IR, Type, "", Lru) ->
+ link_or_image_data(Cs, IR, Type, "", [C|Lru]);
+link_or_image_data([C|Cs], {inline, read_title} = IRT, Type, Eltit, Lru) ->
+ link_or_image_data(Cs, IRT, Type, [C|Eltit], Lru);
+link_or_image_data([_|Cs], {inline, drop}, Type, Eltit, Lru) ->
+ link_or_image_data(Cs, {inline, drop}, Type, Eltit, Lru);
+
+link_or_image_data("[]"++Cs, none, _Type, "", "") ->
+ {delayed, text, Cs};
+link_or_image_data([$[|Cs], none, Type, "", "") ->
+ link_or_image_data(Cs, reference, Type, "", "");
+link_or_image_data(_, none, _Type, "", "") ->
+ no;
+link_or_image_data([$]|_Cs], reference, _Type, "", "") ->
+ no;
+link_or_image_data([$]|Cs], reference, _Type, "", Fer) ->
+ {delayed, lists:reverse(ws_strip(Fer)), Cs};
+link_or_image_data([C|Cs], reference, Type, "", Fer) ->
+ link_or_image_data(Cs, reference, Type, "", [C|Fer]).
+
+mk_image(Title, Url) ->
+ ["<image file=\"", text(Url), "\"><icaption>",
+ text(Title), "</icaption></image>"].
+
+mk_link(Text, Url) ->
+ case chk_proto(Url) of
+ true -> ["<url href=\"", text(Url), "\">", text(Text), "</url>"];
+ false -> ["<seealso marker=\"", text(Url), "\">", text(Text), "</seealso>"]
+ end.
+
+chk_proto("://" ++ _) ->
+ true;
+chk_proto([]) ->
+ false;
+chk_proto([_|Cs]) ->
+ chk_proto(Cs).
+
+%%
+%% Code
+%%
+
+code(Line) ->
+ code(Line, []).
+
+code("%ERTS-VSN%" ++ Cs, Acc) ->
+ code(Cs, ["@ERTS_VSN@"|Acc]);
+code("%OTP-REL%" ++ Cs, Acc) ->
+ code(Cs, ["@OTP_REL@"|Acc]);
+
+code([$<|Cs], Acc) ->
+ code(Cs, ["&lt;"|Acc]);
+code([$>|Cs], Acc) ->
+ code(Cs, ["&gt;"|Acc]);
+code([$&|Cs], Acc) ->
+ code(Cs, ["&amp;"|Acc]);
+code([$'|Cs], Acc) ->
+ code(Cs, ["&apos;"|Acc]);
+code([C|Cs], Acc) ->
+ code(Cs, [C|Acc]);
+code([], Acc) ->
+ lists:reverse(Acc).
+
+end_code(#state{code = true} = S) ->
+ put_line(S#state{code = false, code_blank = []}, "</code>");
+end_code(S) ->
+ S.
+
+strip_code_blank(_Lvls, []) ->
+ [];
+strip_code_blank(Lvls, CBs) ->
+ strip_code_blank(Lvls, CBs, []).
+
+strip_code_blank(_Lvls, [], Acc) ->
+ Acc;
+strip_code_blank(Lvls, [CB|CBs], Acc) ->
+ strip_code_blank(Lvls, CBs, [strip_lvls(Lvls, CB)|Acc]).
+
+strip_lvls(0, Str) ->
+ Str;
+strip_lvls(N, " " ++ Str) ->
+ strip_lvls(N-1, Str);
+strip_lvls(N, [$\t | Str]) ->
+ strip_lvls(N-1, Str);
+strip_lvls(_N, Str) ->
+ Str.
+
+%%
+%% Titles and sections
+%%
+
+put_title(S, 1, Title) ->
+ header(chk_h1(1, S#state{h = 1, mlist = [top]}), Title);
+put_title(#state{mlist = MList0,
+ toc = TOC,
+ smarker_ix = SMarkerIX} = S0, H, Title) ->
+ TitleStr = text(Title),
+ MList1 = [mk_lvl_marker(Title) | MList0],
+ Marker = mk_marker(MList1),
+ S1 = chk_h1(H,
+ S0#state{toc = [TOC,
+ lists:duplicate(H," "),
+ " ",
+ "<seealso marker=\"#",Marker,"\">",
+ TitleStr,"</seealso>",nl()],
+ h = H,
+ mlist = MList1,
+ smarker_ix = false}),
+ true = is_integer(SMarkerIX),
+ S2 = write_delayed(S1, SMarkerIX, ["<marker id=\"", Marker, "\"/>",nl()]),
+ {STag, ETag} = case H > ?MAX_HEADING of
+ true -> {"<p><b>", "</b></p>"};
+ false -> {"<title>", "</title>"}
+ end,
+ put_chars(S2, [STag, TitleStr, ETag, nl()]).
+
+setext_heading(H, #state{line = Line, h = OldH} = S0) ->
+ S1 = sections(H, OldH, S0),
+ put_title(S1, H, ws_strip(Line)).
+
+atx_heading(#state{line = Line, h = OldH} = S0) ->
+ {H, Title} = get_atx_title(Line),
+ S1 = sections(H, OldH, S0),
+ put_title(S1, H, ws_strip(Title)).
+
+
+get_atx_title(Line) ->
+ get_atx_title(Line, 0).
+
+get_atx_title("#" ++ Rest, H) ->
+ get_atx_title(Rest, H+1);
+get_atx_title(Rest, H) ->
+ {H, atx_strip(Rest)}.
+
+atx_strip(S) ->
+ strip(S, [$ ,$\t,$\n,$\r,$#]).
+
+chk_h1(1, #state{have_h1 = true, ifile = {File, _}, line_no = Line}) ->
+ error(File, Line, "Multiple H1 headings~n", []);
+chk_h1(1, #state{have_h1 = false} = S) ->
+ S#state{have_h1 = true};
+chk_h1(_H, S) ->
+ S.
+
+sections(0, 0, S) ->
+ S;
+sections(H, H, #state{mlist = [_|ML], toc = TOC} = S0) ->
+ S1 = S0#state{mlist = ML,
+ toc = [TOC,
+ lists:duplicate(H," "),
+ "</item><item>",nl()]},
+ S2 = end_section(H, S1),
+ begin_section(H, S2);
+sections(H, OldH, S) ->
+ sections_change(H, OldH, S).
+
+sections_change(H, H, S) ->
+ S;
+sections_change(H, OldH, #state{ifile = {File, _},
+ line_no = Line}) when H > OldH+1 ->
+ error(File, Line, "Level ~p heading without preceding level "
+ "~p heading~n", [H, H-1]);
+sections_change(H, OldH, #state{toc = TOC} = S0) when H == OldH+1 ->
+ S1 = case H > 1 of
+ false -> S0;
+ true-> S0#state{toc = [TOC, lists:duplicate(H-1," "),
+ "<list type=\"ordered\"><item>",nl()]}
+ end,
+ S2 = begin_section(H, S1),
+ sections_change(H, OldH+1, S2);
+sections_change(H, OldH, #state{mlist = [_|ML], toc = TOC} = S0) ->
+ S1 = case OldH > 1 of
+ false -> S0;
+ true-> S0#state{toc = [TOC, lists:duplicate(OldH-1," "),
+ "</item></list>",nl()]}
+ end,
+ S2 = end_section(OldH, S1),
+ sections(H, OldH-1, S2#state{mlist = ML}).
+
+begin_section(1, S) ->
+ put_line(S, "<chapter>");
+begin_section(H, #state{delayed_array_ix = IX} = S0) when H > ?MAX_HEADING ->
+ false = S0#state.smarker_ix,
+ true = is_integer(IX),
+ put_delayed(S0#state{smarker_ix = IX, delayed_array_ix = IX+1}, IX);
+begin_section(H, #state{delayed_array_ix = IX} = S0) when H > 1 ->
+ false = S0#state.smarker_ix,
+ true = is_integer(IX),
+ S1 = put_delayed(S0#state{smarker_ix = IX, delayed_array_ix = IX+1}, IX),
+ put_line(S1, "<section>");
+begin_section(_H, S) ->
+ S.
+
+end_section(1, S) ->
+ put_chars(S, ["</chapter>",nl(),nl()]);
+end_section(H, S) when H < 1; ?MAX_HEADING < H ->
+ S;
+end_section(_H, S) ->
+ put_chars(S, ["</section>",nl(),nl()]).
+
+mk_lvl_marker([C|Cs]) when $a =< C, C =< $z ->
+ [C|mk_lvl_marker(Cs)];
+mk_lvl_marker([C|Cs]) when $A =< C, C =< $Z ->
+ [C|mk_lvl_marker(Cs)];
+mk_lvl_marker([C|Cs]) when C == $ ; C == $\t ->
+ [$-|mk_lvl_marker(Cs)];
+mk_lvl_marker([_|Cs]) ->
+ mk_lvl_marker(Cs);
+mk_lvl_marker([]) ->
+ [].
+
+mk_marker([L|Ls]) ->
+ mk_marker(Ls, L).
+
+mk_marker([top], Res) ->
+ Res;
+mk_marker([L|Ls], Res) ->
+ mk_marker(Ls, [L,$_|Res]).
+
+header(#state{ofile = {File, _}} = S0, Title) ->
+ {Year, Month, Day} = erlang:date(),
+ S1 = put_line(S0, "<header>"),
+ S2 = put_delayed(S1, ?DELAYED_COPYRIGHT_IX),
+ S3 = put_chars(S2,
+ ["<title>", text(Title), "</title>", nl(),
+ "<prepared>emd2exml</prepared>", nl(),
+ "<responsible>emd2exml</responsible>", nl(),
+ "<docno>1</docno>", nl(),
+ "<approved>yes</approved>", nl(),
+ "<checked>yes</checked>", nl(),
+ "<date>",
+ integer_to_list(Year), "-",
+ integer_to_list(Month), "-",
+ integer_to_list(Day),
+ "</date>", nl(),
+ "<rev>1</rev>", nl(),
+ "<file>",File,"</file>", nl(),
+ "</header>", nl()]),
+ put_delayed(S3, ?DELAYED_TOC_IX).
+
+
+create_copyright_notice(#state{copyright_data = CRD} = S) ->
+ {From, To, Holder, Legal} = parse_crd(CRD, [], [], [], []),
+ write_delayed(S,
+ ?DELAYED_COPYRIGHT_IX,
+ ["<copyright>", nl(),
+ "<year>", From, "</year>", nl(),
+ "<year>", To, "</year>", nl(),
+ "<holder>", code(Holder),"</holder>", nl(),
+ "</copyright>", nl(),
+ "<legalnotice>", nl(),
+ code(Legal),
+ "</legalnotice>", nl(), nl()]).
+
+create_toc(#state{toc = TOC} = S) ->
+ case read_delayed(S, "?TOC") of
+ {value,{"true",[]}} ->
+ write_delayed(S,
+ ?DELAYED_TOC_IX,
+ ["<p><b>Table of Contents</b></p>", nl(), TOC]);
+ _ ->
+ write_delayed(S, ?DELAYED_TOC_IX, "")
+ end.
+
+parse_crd([], From, To, Holder, Legal) ->
+ {Year, _, _} = erlang:date(),
+ {case From of
+ [] -> integer_to_list(Year);
+ _ -> From
+ end,
+ case To of
+ [] -> integer_to_list(Year);
+ _ -> To
+ end,
+ case Holder of
+ [] -> "Ericsson AB. All Rights Reserved.";
+ _ -> Holder
+ end,
+ case Legal of
+ [] ->
+ ["The contents of this file are subject to the Erlang Public License,", nl(),
+ "Version 1.1, (the \"License\"); you may not use this file except in", nl(),
+ "compliance with the License. You should have received a copy of the", nl(),
+ "Erlang Public License along with this software. If not, it can be", nl(),
+ "retrieved online at http://www.erlang.org/.", nl(),
+ nl(),
+ "Software distributed under the License is distributed on an \"AS IS\"", nl(),
+ "basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See", nl(),
+ "the License for the specific language governing rights and limitations", nl(),
+ "under the License.", nl()];
+ _ -> Legal
+ end};
+parse_crd([Line|Lines], OldFrom, OldTo, OldHolder, Legal) ->
+ case copyright_line(Line) of
+ no -> parse_crd(Lines, OldFrom, OldTo, OldHolder, [code(Line)|Legal]);
+ {From, To, Holder} -> parse_crd(Lines, From, To, code(Holder), Legal)
+ end.
+
+copyright_line(Line) ->
+ case copyright_line(Line, start, [], []) of
+ {From, To} -> {From, To, Line};
+ _ -> no
+ end.
+
+copyright_line([], start, _, _) ->
+ no;
+copyright_line([], _, [], []) ->
+ {[], []};
+copyright_line([], _, F, []) ->
+ Year = lists:reverse(F),
+ {Year, Year};
+copyright_line("opyright "++Cs, start, [], []) ->
+ copyright_line(Cs, find_from, [], []);
+copyright_line([_|Cs], start, [], []) ->
+ copyright_line(Cs, start, [], []);
+copyright_line([C|Cs], find_from, [], []) when $0 =< C, C =< $9 ->
+ copyright_line(Cs, from, [C|[]], []);
+copyright_line([_|Cs], find_from, [], []) ->
+ copyright_line(Cs, find_from, [], []);
+copyright_line([C|Cs], from, F, []) when $0 =< C, C =< $9 ->
+ copyright_line(Cs, from, [C|F], []);
+copyright_line([_|Cs], from, F, []) ->
+ copyright_line(Cs, find_to, F, []);
+copyright_line([C|Cs], find_to, F, []) when $0 =< C, C =< $9 ->
+ copyright_line(Cs, to, F, [C|[]]);
+copyright_line([_|Cs], find_to, F, []) ->
+ copyright_line(Cs, find_to, F, []);
+copyright_line([C|Cs], to, F, T) when $0 =< C, C =< $9 ->
+ copyright_line(Cs, to, F, [C|T]);
+copyright_line(_, to, F, T) ->
+ {lists:reverse(F), lists:reverse(T)}.
+
+%%
+%% Lists
+%%
+
+put_list_p(#state{list_p_stack = [{_, IX} | _]} = S, start) ->
+ put_delayed(S#state{list_p = true}, IX);
+put_list_p(#state{list_p_stack = [{_, IX} | _]} = S, stop) ->
+ put_delayed(S#state{list_p = false}, IX+1).
+
+list_use_p(#state{list_p_stack = [{unknown, IX} | LPS]} = S0, yes) ->
+ S1 = write_delayed(S0, IX, "<p>"),
+ S2 = write_delayed(S1, IX+1, "</p>"),
+ S2#state{list_p_stack = [{yes, IX} | LPS]};
+list_use_p(#state{list_p_stack = [{unknown, IX} | LPS]} = S0, no) ->
+ S1 = write_delayed(S0, IX, ""),
+ S2 = write_delayed(S1, IX+1, ""),
+ S2#state{list_p_stack = [{no, IX} | LPS]};
+list_use_p(S, _) ->
+ S.
+
+list_chk_nxt_line(#state{list_p = false} = S) ->
+ S;
+list_chk_nxt_line(#state{next_type = {text, _}} = S) ->
+ S;
+list_chk_nxt_line(S) ->
+ put_line(put_list_p(S, stop), "").
+
+list_item(#state{list_lvl = OldLvl} = S0, ListType, ListLvl) ->
+ NewLvl = case ListLvl > OldLvl of
+ true -> OldLvl+1;
+ false -> ListLvl+1
+ end,
+ S1 = chg_list_lvl(S0, ListType, NewLvl),
+ case NewLvl =< OldLvl of
+ false ->
+ S1;
+ true ->
+ case S1#state.list_type_stack of
+ [ListType|_] ->
+ %% New item in old list
+ put_chars(S1, ["</item>", nl(), "<item>", nl()]);
+ [_|LTS] ->
+ %% New item in new list
+ [_ | LPS] = S1#state.list_p_stack,
+ IX = S1#state.delayed_array_ix,
+ S2 = list_use_p(S1, no), % Ignored if already determined
+ S3 = put_line(S2, list_end_tags()),
+ S4 = put_line(S3, list_begin_tags(ListType)),
+ S4#state{list_type_stack = [ListType|LTS],
+ list_p_stack = [{unknown, IX} | LPS],
+ delayed_array_ix = IX+2}
+ end
+ end.
+
+list_begin_tags(uolist) ->
+ "<list type=\"bulleted\"><item>";
+list_begin_tags(olist) ->
+ "<list type=\"ordered\"><item>".
+
+list_end_tags() ->
+ "</item></list>".
+
+chg_list_lvl(#state{list_lvl = Lvl} = S, Lvl) ->
+ S;
+chg_list_lvl(#state{list_lvl = OldLvl,
+ list_type_stack = [ListType|_]} = S,
+ NewLvl) when OldLvl > NewLvl ->
+ chg_list_lvl(S, ListType, NewLvl).
+
+chg_list_lvl(#state{list_lvl = Lvl} = S, _ListType, Lvl) ->
+ S;
+chg_list_lvl(#state{list_p_stack = LPS,
+ list_type_stack = LTS,
+ delayed_array_ix = IX,
+ list_lvl = OldLvl} = S,
+ ListType,
+ Lvl) when OldLvl < Lvl ->
+ chg_list_lvl(put_line(S#state{list_type_stack = [ListType|LTS],
+ list_p_stack = [{unknown, IX} | LPS],
+ delayed_array_ix = IX+2,
+ list_lvl = OldLvl+1},
+ list_begin_tags(ListType)),
+ Lvl);
+chg_list_lvl(#state{list_p_stack = [_ | LPS],
+ list_type_stack = [_|LTS],
+ list_lvl = OldLvl} = S0,
+ ListType,
+ Lvl) ->
+ S1 = list_use_p(S0, no), % Ignored if already determined
+ chg_list_lvl(put_line(S1#state{list_p_stack = LPS,
+ list_type_stack = LTS,
+ list_lvl = OldLvl-1},
+ list_end_tags()),
+ ListType,
+ Lvl).
+
+list_strip(uolist, Str) ->
+ case list_strip(Str) of
+ [C | Cs] when C == $*; C == $+; C == $- ->
+ list_strip(Cs);
+ _ ->
+ exit({unexpected_unordered_list_item, Str})
+ end;
+list_strip(olist, Str) ->
+ case strip_head(list_strip(Str), lists:seq($0, $9)) of
+ [$. | Cs] ->
+ list_strip(Cs);
+ _ ->
+ exit({unexpected_ordered_list_item, Str})
+ end.
+
+list_strip(S) ->
+ strip_head(S, [$ ,$\t]).
+
+%%
+%% Block quote
+%%
+
+rm_bquote(0, 0, Str) ->
+ Str;
+rm_bquote(0, BQLvl, [$>|Cs]) ->
+ rm_bquote(0, BQLvl-1, Cs);
+rm_bquote(0, BQLvl, [C|Cs]) when C == $ ; C == $\t ->
+ rm_bquote(0, BQLvl, Cs);
+rm_bquote(TxtLvl, BQLvl, " " ++ Cs) ->
+ " " ++ rm_bquote(TxtLvl-1, BQLvl, Cs);
+rm_bquote(TxtLvl, BQLvl, [$\t|Cs]) ->
+ [$\t | rm_bquote(TxtLvl-1, BQLvl, Cs)].
+
+chg_bq_lvl(Lvl, #state{bq_lvl = Lvl} = S) ->
+ S;
+chg_bq_lvl(NewLvl, #state{bq_lvl = Lvl} = S) when NewLvl > Lvl ->
+ chg_bq_lvl(NewLvl,
+ put_line(end_p(end_code(S#state{bq_lvl = Lvl+1})), "<blockquote>"));
+chg_bq_lvl(NewLvl, #state{bq_lvl = Lvl} = S) ->
+ chg_bq_lvl(NewLvl,
+ put_line(end_p(end_code(S#state{bq_lvl = Lvl-1})), "</blockquote>")).
+
+%%
+%% Resolve link
+%%
+
+resolve_link(#state{line = Line} = S) ->
+ {Key, Url, Title} = resolve_link(Line, start, "", "", ""),
+ write_delayed(S, Key, {Url, Title}).
+
+resolve_link("[" ++ Rest, start, "", "", "") ->
+ resolve_link(Rest, key, "", "", "");
+resolve_link([_|Cs], start, "", "", "") ->
+ resolve_link(Cs, start, "", "", "");
+resolve_link("]:" ++ Rest, key, Yek, "", "") ->
+ resolve_link(Rest, url, Yek, "", "");
+resolve_link([C|Cs], url, Yek, Lru, "") when C == $"; C == $' ->
+ resolve_link(Cs, {title, C}, Yek, Lru, "");
+resolve_link([$(|Cs], url, Yek, Lru, "") ->
+ resolve_link(Cs, {title, $)}, Yek, Lru, "");
+resolve_link([C|Cs], {title, C}, Yek, Lru, Eltit) ->
+ resolve_link(Cs, drop, Yek, Lru, Eltit);
+resolve_link([C|Cs], key, Yek, "", "") ->
+ resolve_link(Cs, key, [C|Yek], "", "");
+resolve_link([C|Cs], url, Yek, Lru, "") ->
+ resolve_link(Cs, url, Yek, [C|Lru], "");
+resolve_link([C|Cs], {title, _} = T, Yek, Lru, Eltit) ->
+ resolve_link(Cs, T, Yek, Lru, [C|Eltit]);
+resolve_link([_|Cs], drop, Yek, Lru, Eltit) ->
+ resolve_link(Cs, drop, Yek, Lru, Eltit);
+resolve_link([], _, Yek, Lru, Eltit) ->
+ {ws_strip(lists:reverse(Yek)),
+ ws_strip(lists:reverse(Lru)),
+ ws_strip(lists:reverse(Eltit))}.
+
+%%
+%% Misc
+%%
+
+ws_strip(S) ->
+ strip(S, [$ ,$\t,$\n,$\r]).
+
+%ws_strip_head(S) ->
+% strip_head(S, [$ ,$\t,$\n,$\r]).
+
+%hws_strip_head(S) ->
+% strip_head(S, [$ ,$\t]).
+
+%hws_strip(S) ->
+% strip(S, [$ ,$\t]).
+
+strip([], _StripList) ->
+ [];
+strip([C|Cs] = Str, StripList) ->
+ case lists:member(C, StripList) of
+ true -> strip(Cs, StripList);
+ false -> lists:reverse(pirts(lists:reverse(Str), StripList))
+ end.
+
+pirts([], _StripList) ->
+ [];
+pirts([C|Cs] = Str, StripList) ->
+ case lists:member(C, StripList) of
+ true -> pirts(Cs, StripList);
+ false -> Str
+ end.
+
+strip_head([C|Cs] = Str, StripList) ->
+ case lists:member(C, StripList) of
+ true -> strip_head(Cs, StripList);
+ false -> Str
+ end.
+
+type("[" ++ Cs) ->
+ type_resolve_link(Cs);
+type(" [" ++ Cs) ->
+ type_resolve_link(Cs);
+type("==" ++ Cs) ->
+ case type_same(Cs, $=) of
+ true -> {marker, h1};
+ _ -> {text, 0}
+ end;
+type("--" ++ Cs) ->
+ case type_same(Cs, $-) of
+ true -> {marker, h2};
+ _ -> {text, 0}
+ end;
+type(Str) ->
+ type_cont(Str).
+
+type_resolve_link([]) ->
+ {text, 0};
+type_resolve_link("]:" ++ _) ->
+ resolve_link;
+type_resolve_link([_|Cs]) ->
+ type_resolve_link(Cs).
+
+type_bquote(Str, N) ->
+ case type(Str) of
+ {bquote, N, M} ->
+ {bquote, N, M+1};
+ _ ->
+ {bquote, N, 1}
+ end.
+
+type_same([C|Cs], C) ->
+ type_same(Cs, C);
+type_same([_|Cs], _) ->
+ case type_cont(Cs) of
+ blank -> true;
+ _ -> false
+ end.
+
+type_cont(Str) ->
+ type_cont(Str, 0, true).
+
+type_cont(" " ++ Str, N, true) ->
+ type_cont(Str, N+1, true);
+type_cont([$\t| Str], N, true) ->
+ type_cont(Str, N+1, true);
+type_cont([C|Str], N, _) when C == $ ; C == $\t; C == $\n; C == $\r ->
+ type_cont(Str, N, false);
+type_cont([], _, _) ->
+ blank;
+type_cont(">" ++ Cs, N, _) ->
+ type_bquote(Cs, N);
+type_cont(" >" ++ Cs, N, _) ->
+ type_bquote(Cs, N);
+type_cont(" >" ++ Cs, N, _) ->
+ type_bquote(Cs, N);
+type_cont(" >" ++ Cs, N, _) ->
+ type_bquote(Cs, N);
+type_cont([C,$ |_], N, _) when C == $*; C == $+; C == $- ->
+ {uolist, N};
+type_cont([C,$\t |_], N, _) when C == $*; C == $+; C == $- ->
+ {uolist, N};
+type_cont([C|Cs], N, _) when $0 =< C, C =< $9 ->
+ case type_olist(Cs) of
+ true -> {olist, N};
+ false -> {text, N}
+ end;
+type_cont("%CopyrightBegin%" ++ _, _, _) ->
+ copyright_begin;
+type_cont("%CopyrightEnd%" ++ _, _, _) ->
+ copyright_end;
+type_cont(_, N, _) ->
+ {text, N}.
+
+type_olist([C|Cs]) when $0 =< C, C =< $9 ->
+ type_olist(Cs);
+type_olist([$.,$ |_]) ->
+ true;
+type_olist([$.,$\t|_]) ->
+ true;
+type_olist(_) ->
+ false.
+
+end_all(S) ->
+ chg_list_lvl(end_p(end_code(S)), 0).
+
+get_line(#state{next_line = eof} = S) ->
+ S#state{prev_line = S#state.line,
+ prev_type = S#state.type,
+ line = eof,
+ type = blank,
+ bq_type = 0};
+get_line(#state{ifile = IFile, line_no = LNO, copyright = CR} = S0) ->
+ NewLine = file_read_line(IFile, LNO),
+ S1 = case {CR, type(NewLine)} of
+ {false, copyright_begin} ->
+ S0#state{copyright = true,
+ next_line = "",
+ next_type = blank};
+ {true, copyright_end} ->
+ S0#state{copyright = false,
+ next_line = "",
+ next_type = blank};
+ {true, NextType} ->
+ S0#state{next_line = NewLine,
+ next_type = NextType,
+ copyright_data = [NewLine|S0#state.copyright_data]};
+ {false, NextType} ->
+ S0#state{next_line = NewLine,
+ next_type = NextType}
+ end,
+ S1#state{line_no = S0#state.line_no + 1,
+ line = S0#state.next_line,
+ type = S0#state.next_type,
+ bq_type = S0#state.bq_next_type,
+ prev_line = S0#state.line,
+ prev_type = S0#state.type,
+ bq_next_type = 0}.
+
+write_delayed(#state{delayed_array = DA} = S,
+ IX,
+ Value) when is_integer(IX) ->
+ S#state{delayed_array = array:set(IX, Value, DA)};
+write_delayed(#state{delayed_tree = DT} = S, Key, Value) ->
+ S#state{delayed_tree = gb_trees:enter(Key, Value, DT)}.
+
+read_delayed(#state{delayed_array = DA}, IX) when is_integer(IX) ->
+ array:get(IX, DA);
+read_delayed(#state{delayed_tree = DT}, Key) ->
+ gb_trees:lookup(Key, DT).
+
+put_delayed(#state{out = Out} = S, Key) ->
+ S#state{out = [{delayed, Key} | Out]}.
+
+put_delayed(#state{out = Out} = S, Key, Data) ->
+ S#state{out = [{delayed, Key, Data} | Out]}.
+
+put_chars(#state{out = Out} = S, Chars) ->
+ S#state{out = [[Chars] | Out]}.
+
+put_line(#state{out = Out} = S, String) ->
+ S#state{out = [[String, nl()] | Out]}.
+
+complete_output(#state{out = Out} = S) ->
+ complete_output(create_copyright_notice(create_toc(S)), Out, []).
+
+complete_output(S, [], Out) ->
+ S#state{delayed_array = [],
+ out = ["<?xml version=\"1.0\" encoding=\"utf8\" ?>", nl(),
+ "<!DOCTYPE chapter SYSTEM \"chapter.dtd\">", nl(),
+ Out]};
+complete_output(S, [{delayed, IX}|Rest], Out) ->
+ complete_output(S, Rest, [read_delayed(S, IX)|Out]);
+complete_output(S, [{delayed, Key, {link, Text, Line}}|Rest], Out) ->
+ case read_delayed(S, Key) of
+ {value, {Url, _Title}} ->
+ complete_output(S, Rest, [mk_link(Text, Url)|Out]);
+ none ->
+ {File, _} = S#state.ifile,
+ error(File, Line, "Link definition name `~ts' not found~n", [Key])
+ end;
+complete_output(S, [{delayed, Key, {image, _Text, Line}}|Rest], Out) ->
+ case read_delayed(S, Key) of
+ {value, {Url, Title}} ->
+ complete_output(S, Rest, [mk_image(Title, Url)|Out]);
+ none ->
+ {File, _} = S#state.ifile,
+ error(File, Line, "Image definition name `~ts' not found~n", [Key])
+ end;
+complete_output(S, [Next|Rest], Out) ->
+ complete_output(S, Rest, [Next|Out]).
+
+write_output(_OFD, []) ->
+ ok;
+write_output(OFD, [O|Os]) ->
+ file_write(OFD, O),
+ write_output(OFD, Os).
+
+error(FStr, Args) ->
+ io:format(standard_error, "ERROR: " ++ FStr ++ "~n", Args),
+ stop(1).
+
+error(File, Line, FStr, Args) ->
+ io:format(standard_error, "~s:~p: ERROR: " ++ FStr ++ "~n",
+ [File | [Line | Args]]),
+ stop(1).
+
+stop() -> init:stop(), receive after infinity -> ok end.
+stop(Status) -> init:stop(Status), receive after infinity -> ok end.
+
+%%
+%% I/O
+%%
+
+nl() ->
+ io_lib:nl().
+
+file_wopen(File) ->
+ case file:open(File, [write, delayed_write]) of
+ {ok, FD} -> {File, FD};
+ {error, Reason} -> error("Failed to open `~s' for writing: ~p~n",
+ [File, Reason])
+ end.
+
+file_ropen(File) ->
+ case file:open(File, [read, binary]) of
+ {ok, FD} -> {File, FD};
+ {error, Reason} -> error("Failed to open `~s' for reading: ~p~n",
+ [File, Reason])
+ end.
+
+file_read_line({File, FD}, LineNo) ->
+ case file:read_line(FD) of
+ {ok, Line} -> unicode:characters_to_list(Line, utf8);
+ eof -> eof;
+ {error, Error} -> error(File,LineNo,"Reading line failed: ~p~n",[Error])
+ end.
+
+file_write({File, FD}, Data) ->
+ case file:write(FD, unicode:characters_to_binary(Data, unicode, utf8)) of
+ ok -> ok;
+ {error, Reason} ->
+ error("Writing to file `~s' failed: ~p~n", [File, Reason])
+ end.
+
+file_close({File, FD}) ->
+ case file:close(FD) of
+ ok -> ok;
+ {error, Reason} -> error("Closing file `~s' failed: ~p~n",[File,Reason])
+ end.
+
+%%
+%% EOF
+%%
diff --git a/otp_build b/otp_build
index ad9d38ebca..67608138f7 100755
--- a/otp_build
+++ b/otp_build
@@ -915,7 +915,7 @@ do_primary_git ()
bootstrap/lib/compiler \
bootstrap/lib/orber/include \
bootstrap/bin
- git commit -m 'Update primary bootstrap'
+ git commit --no-verify -m 'Update primary bootstrap'
}
diff --git a/system/doc/efficiency_guide/advanced.xml b/system/doc/efficiency_guide/advanced.xml
index 0ec3afbd59..7898f925b9 100644
--- a/system/doc/efficiency_guide/advanced.xml
+++ b/system/doc/efficiency_guide/advanced.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2001</year><year>2009</year>
+ <year>2001</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>Advanced</title>
@@ -154,7 +154,8 @@ On 64-bit architectures: 4 words for a reference from the current local node, an
<item>255</item>
<tag><em>Atoms </em></tag>
<item> <marker id="atoms"></marker>
-The maximum number of atoms is 1048576. </item>
+ By default, the maximum number of atoms is 1048576.
+ This limit can be raised or lowered using the <c>+t</c> option.</item>
<tag><em>Ets-tables</em></tag>
<item>The default is 1400, can be changed with the environment variable <c>ERL_MAX_ETS_TABLES</c>.</item>
<tag><em>Elements in a tuple</em></tag>
@@ -175,7 +176,7 @@ The maximum number of atoms is 1048576. </item>
<tag><em>Total amount of data allocated by an Erlang node</em></tag>
<item>The Erlang runtime system can use the complete 32 (or 64) bit address space,
but the operating system often limits a single process to use less than that.</item>
- <tag><em>length of a node name</em></tag>
+ <tag><em>Length of a node name</em></tag>
<item>An Erlang node name has the form host@shortname or host@longname. The node name is
used as an atom within the system so the maximum size of 255 holds for the node name too.</item>
<tag><em>Open ports</em></tag>
diff --git a/system/doc/efficiency_guide/commoncaveats.xml b/system/doc/efficiency_guide/commoncaveats.xml
index e18e5aa510..61d13636c0 100644
--- a/system/doc/efficiency_guide/commoncaveats.xml
+++ b/system/doc/efficiency_guide/commoncaveats.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2001</year><year>2009</year>
+ <year>2001</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>Common Caveats</title>
@@ -69,7 +69,7 @@
<p>Atoms are not garbage-collected. Once an atom is created, it will never
be removed. The emulator will terminate if the limit for the number
- of atoms (1048576) is reached.</p>
+ of atoms (1048576 by default) is reached.</p>
<p>Therefore, converting arbitrary input strings to atoms could be
dangerous in a system that will run continuously.
diff --git a/system/doc/efficiency_guide/functions.xml b/system/doc/efficiency_guide/functions.xml
index d55b60e39c..fe14a4f000 100644
--- a/system/doc/efficiency_guide/functions.xml
+++ b/system/doc/efficiency_guide/functions.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2001</year><year>2009</year>
+ <year>2001</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>Functions</title>
@@ -179,7 +179,9 @@ explicit_map_pairs(Map, Xs0, Ys0) ->
A "tuple fun", <c>{Module,Function}</c>, is not a fun.
The cost for calling a "tuple fun" is similar to that
of <c>apply/3</c> or worse. Using "tuple funs" is <em>strongly discouraged</em>,
- as they may not be supported in a future release.</p></warning>
+ as they may not be supported in a future release,
+ and because there exists a superior alternative since the R10B
+ release, namely the <c>fun Module:Function/Arity</c> syntax.</p></warning>
<p><c>apply/3</c> must look up the code for the function to execute
in a hash table. Therefore, it will always be slower than a
diff --git a/system/doc/efficiency_guide/myths.xml b/system/doc/efficiency_guide/myths.xml
index 76a72368bb..65113c9372 100644
--- a/system/doc/efficiency_guide/myths.xml
+++ b/system/doc/efficiency_guide/myths.xml
@@ -168,8 +168,8 @@ vanilla_reverse([], Acc) ->
<p>Actually, string handling could be slow if done improperly.
In Erlang, you'll have to think a little more about how the strings
are used and choose an appropriate representation and use
- the <seealso marker="stdlib:re">re</seealso> instead of the obsolete
- <c>regexp</c> module if you are going to use regualr expressions.</p>
+ the <seealso marker="stdlib:re">re</seealso> module instead of the obsolete
+ <c>regexp</c> module if you are going to use regular expressions.</p>
</section>
<section>
diff --git a/system/doc/getting_started/robustness.xml b/system/doc/getting_started/robustness.xml
index 227da4c027..c141530fe0 100644
--- a/system/doc/getting_started/robustness.xml
+++ b/system/doc/getting_started/robustness.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2003</year><year>2009</year>
+ <year>2003</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>Robustness</title>
@@ -146,7 +146,7 @@ after pong_timeout() -></code>
a process calls
<seealso marker="erts:erlang#link/1">link(Other_Pid)</seealso>
it sets up a bidirectional link between itself and the process
- called <c>Other_Pid</c>. When a process terminates its sends
+ called <c>Other_Pid</c>. When a process terminates, it sends
something called a <em>signal</em> to all the processes it has
links to.</p>
<p>The signal carries information about the pid it was sent from and
diff --git a/system/doc/installation_guide/Makefile b/system/doc/installation_guide/Makefile
index 854025765c..a47d77604d 100644
--- a/system/doc/installation_guide/Makefile
+++ b/system/doc/installation_guide/Makefile
@@ -31,6 +31,7 @@ APPLICATION=otp-system-documentation
# Release directory specification
# ----------------------------------------------------
RELSYSDIR = $(RELEASE_PATH)/doc/installation_guide
+REDIRECT_HTML_RELSYSDIR = $(RELSYSDIR)/source
# ----------------------------------------------------
# Target Specs
@@ -54,14 +55,11 @@ XML_FILES = \
$(XML_PART_FILES)
# ----------------------------------------------------
-# Install readme files
-# ----------------------------------------------------
-SOURCE_INSTALL_READMES = \
- $(ERL_TOP)/INSTALL.html \
- $(ERL_TOP)/INSTALL-CROSS.html \
- $(ERL_TOP)/INSTALL-WIN32.html
+GENERATED_XML_FILES = \
+ INSTALL.xml \
+ INSTALL-CROSS.xml \
+ INSTALL-WIN32.xml
-SOURCE_RELSYSDIR = $(RELSYSDIR)/source
# ----------------------------------------------------
HTML_FILES = \
@@ -71,6 +69,12 @@ HTMLDIR = ../html/installation_guide
HTML_UG_FILE = $(HTMLDIR)/users_guide.html
+REDIRECT_HTML_DIR = $(HTMLDIR)/source
+REDIRECT_HTML_FILES = \
+ $(REDIRECT_HTML_DIR)/INSTALL.html \
+ $(REDIRECT_HTML_DIR)/INSTALL-CROSS.html \
+ $(REDIRECT_HTML_DIR)/INSTALL-WIN32.html
+
# ----------------------------------------------------
# FLAGS
# ----------------------------------------------------
@@ -80,15 +84,32 @@ DVIPS_FLAGS +=
# ----------------------------------------------------
# Targets
# ----------------------------------------------------
-docs: html
+
+%.xml: $(ERL_TOP)/%.md $(ERL_TOP)/make/emd2exml
+ $(ERL_TOP)/make/emd2exml $< $@
+
+$(REDIRECT_HTML_DIR)/%.html: Makefile
+ test -d $(REDIRECT_HTML_DIR) || $(INSTALL_DIR) $(REDIRECT_HTML_DIR)
+ echo "<html><head><meta HTTP-EQUIV=\"REFRESH\"" > $@
+ echo " content=\"5; url=../"$(notdir $@)"\">" >> $@
+ echo "<title>This page has moved</title></head><body>" >> $@
+ echo "<h1>This page has moved</h1>" >> $@
+ echo "<p>You will be automatically redirected to its new" >> $@
+ echo "location in 5 seconds." >> $@
+ echo "This <a href=\"../"$(notdir $@)"\">link</a> will" >> $@
+ echo "take you there immediately.</p></body></html>" >> $@
+
+docs: $(GENERATED_XML_FILES) html
local_docs: PDFDIR=../../pdf
+local_docs: $(GENERATED_XML_FILES)
-html: $(GIF_FILES) $(HTML_UG_FILE)
+html: $(REDIRECT_HTML_FILES) $(GENERATED_XML_FILES) $(GIF_FILES) $(HTML_UG_FILE)
-debug opt:
+debug opt:
clean clean_docs:
+ rm -f $(GENERATED_XML_FILES)
rm -rf $(HTMLDIR)
rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo)
rm -f errs core *~
@@ -102,8 +123,8 @@ include $(ERL_TOP)/make/otp_release_targets.mk
release_docs_spec: docs
$(INSTALL_DIR) $(RELSYSDIR)
$(INSTALL_DATA) $(GIF_FILES) $(HTMLDIR)/*.html $(RELSYSDIR)
- $(INSTALL_DIR) $(SOURCE_RELSYSDIR)
- $(INSTALL_DATA) $(SOURCE_INSTALL_READMES) $(SOURCE_RELSYSDIR)
+ $(INSTALL_DIR) $(REDIRECT_HTML_RELSYSDIR)
+ $(INSTALL_DATA) $(REDIRECT_HTML_FILES) $(REDIRECT_HTML_RELSYSDIR)
release_spec:
diff --git a/system/doc/installation_guide/install.xml b/system/doc/installation_guide/install-binary.xml
index c1b930a4bd..ac4192586d 100644
--- a/system/doc/installation_guide/install.xml
+++ b/system/doc/installation_guide/install-binary.xml
@@ -21,7 +21,7 @@
</legalnotice>
- <title>Installation</title>
+ <title>Installing the Binary Release</title>
<prepared>Peter H&ouml;gfeldt</prepared>
<responsible>Peter H&ouml;gfeldt</responsible>
<docno></docno>
@@ -29,27 +29,10 @@
<checked></checked>
<date>1997-05-26</date>
<rev>C</rev>
- <file>install.xml</file>
+ <file>install-binary.xml</file>
</header>
<section>
- <title>Source</title>
- <p>This document describes installation procedures for
- binary releases. Documentation of build and installation
- procedures for the source release can be found in the source
- tree at the following locations:</p>
- <taglist>
- <tag>Building and Installing Erlang/OTP</tag>
- <item><url href="source/INSTALL.html"><c>$ERL_TOP/INSTALL.md</c></url></item>
- <tag>Cross Compiling Erlang/OTP</tag>
- <item><url href="source/INSTALL-CROSS.html"><c>$ERL_TOP/INSTALL-CROSS.md</c></url></item>
- <tag>How to Build Erlang/OTP on Windows</tag>
- <item><url href="source/INSTALL-WIN32.html"><c>$ERL_TOP/INSTALL-WIN32.md</c></url></item>
- </taglist>
- <p>Where <c>$ERL_TOP</c> is the top directory in the source tree.</p>
- </section>
-
- <section>
<title>UNIX</title>
<section>
@@ -73,7 +56,7 @@
which is <c><![CDATA[<PREFIX>.tar.gz]]></c>, where <c><![CDATA[<PREFIX>]]></c> is a string
denoting the particular Erlang/OTP release, e.g.
<c>otp_LXA_11930_sunos5_R9B</c>.</p>
- <p>Wherever the string <c><![CDATA[<PREFIX>]]></c> is used below, it should
+ <p>Wherever the string <c><![CDATA[<PREFIX>]]></c> is used below, it should
be replaced by the actual name prefix of the compressed tar file.</p>
<p>The tape archive file does not have one single directory in which
all other files are rooted. Therefore the tape archive file must be
@@ -162,4 +145,3 @@ ln -s /usr/local/erlang/otp_r7b/bin/erl /usr/local/bin/erl </pre>
</section>
</section>
</chapter>
-
diff --git a/system/doc/installation_guide/make.dep b/system/doc/installation_guide/make.dep
index 3d1477935d..3878f4ac9d 100644
--- a/system/doc/installation_guide/make.dep
+++ b/system/doc/installation_guide/make.dep
@@ -9,5 +9,5 @@
# TeX files that the DVI file depend on
# ----------------------------------------------------
-book.dvi: book.tex install.tex part.tex verification.tex
+book.dvi: book.tex install-binary.tex part.tex verification.tex
diff --git a/system/doc/installation_guide/part.xml b/system/doc/installation_guide/part.xml
index 3019d2e118..fceacdd8f6 100644
--- a/system/doc/installation_guide/part.xml
+++ b/system/doc/installation_guide/part.xml
@@ -4,7 +4,7 @@
<part xmlns:xi="http://www.w3.org/2001/XInclude">
<header>
<copyright>
- <year>2000</year><year>2009</year>
+ <year>2000</year><year>2010</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -13,12 +13,12 @@
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
-
+
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
-
+
</legalnotice>
<title>Installation Guide</title>
@@ -31,7 +31,10 @@
<description>
<p>How to install Erlang/OTP on UNIX or Windows.</p>
</description>
- <xi:include href="install.xml"/>
+ <xi:include href="install-binary.xml"/>
<xi:include href="verification.xml"/>
+ <xi:include href="INSTALL.xml"/>
+ <xi:include href="INSTALL-CROSS.xml"/>
+ <xi:include href="INSTALL-WIN32.xml"/>
</part>
diff --git a/system/doc/installation_guide/xmlfiles.mk b/system/doc/installation_guide/xmlfiles.mk
index 7e1235b64d..dee67b3c70 100644
--- a/system/doc/installation_guide/xmlfiles.mk
+++ b/system/doc/installation_guide/xmlfiles.mk
@@ -1,21 +1,24 @@
#
# %CopyrightBegin%
-#
-# Copyright Ericsson AB 2009. All Rights Reserved.
-#
+#
+# Copyright Ericsson AB 2009-2010. All Rights Reserved.
+#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
# retrieved online at http://www.erlang.org/.
-#
+#
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
-#
+#
# %CopyrightEnd%
#
INST_GUIDE_CHAPTER_FILES = \
- install.xml \
- verification.xml
+ install-binary.xml \
+ verification.xml \
+ INSTALL.xml \
+ INSTALL-CROSS.xml \
+ INSTALL-WIN32.xml
diff --git a/xcomp/README.md b/xcomp/README.md
index 9f638f46d7..2d79107283 100644
--- a/xcomp/README.md
+++ b/xcomp/README.md
@@ -1,20 +1,23 @@
Cross Compiling Erlang/OTP
==========================
-This document describes how to cross compile Erlang/OTP. Note that the support
-for cross compiling Erlang/OTP should be considered as experimental. As far as
-we know, the R13B04 release should cross compile fine, but since we currently
-have a very limited set of cross compilation environments to test with we
-cannot be sure. The cross compile support will stay in an experimental state
-until we get a lot more cross compilation environments to test with.
+Introduction
+------------
-You are encouraged to read the whole document before attempting to cross
-compile Erlang/OTP. Before reading this document you should read the
-[`$ERL_TOP/INSTALL.md`] [1] document which describes building Erlang/OTP in
-general. `$ERL_TOP` is the top directory in the source tree.
+This document describes how to cross compile Erlang/OTP-%OTP-REL%. Note that
+the support for cross compiling Erlang/OTP should be considered as
+experimental. As far as we know, the %OTP-REL% release should cross compile
+fine, but since we currently have a very limited set of cross compilation
+environments to test with we cannot be sure. The cross compilation support
+will remain in an experimental state until we get a lot more cross compilation
+environments to test with.
-`otp_build` Versus `configure`/`make`
--------------------------------------
+You are advised to read the whole document before attempting to cross
+compile Erlang/OTP. However, before reading this document, you should read
+the [$ERL_TOP/INSTALL.md][] document which describes building and installing
+Erlang/OTP in general. `$ERL_TOP` is the top directory in the source tree.
+
+### otp\_build Versus configure/make ###
Building Erlang/OTP can be done either by using the `$ERL_TOP/otp_build`
script, or by invoking `$ERL_TOP/configure` and `make` directly. Building using
@@ -27,18 +30,17 @@ unless `--enable-dynamic-ssl-lib` has been explicitly passed. The binary
releases that we deliver are built using `otp_build`. The defaults used by
`otp_build configure` may change at any time without prior notice.
-Cross Configuration
--------------------
+### Cross Configuration ###
The `$ERL_TOP/xcomp/erl-xcomp.conf.template` file contains all available cross
configuration variables and can be used as a template when creating a cross
-compilation configuration. All cross configuration variables are also listed
-at the end of this document. For examples of working cross configurations see
-the `$ERL_TOP/xcomp/erl-xcomp-TileraMDE2.0-tilepro.conf` file and the
-`$ERL_TOP/xcomp/erl-xcomp-x86_64-saf-linux-gnu.conf` file. If the default
-behavior of a variable is satisfactory, the variable does not need to be set.
-However, the `configure` script will issue a warning when a default value is
-used. When a variable has been set, no warning will be issued.
+compilation configuration. All [cross configuration variables][] are also
+listed at the end of this document. For examples of working cross
+configurations see the `$ERL_TOP/xcomp/erl-xcomp-TileraMDE2.0-tilepro.conf`
+file and the `$ERL_TOP/xcomp/erl-xcomp-x86_64-saf-linux-gnu.conf` file. If the
+default behavior of a variable is satisfactory, the variable does not need to
+be set. However, the `configure` script will issue a warning when a default
+value is used. When a variable has been set, no warning will be issued.
A cross configuration file can be passed to `otp_build configure` using the
`--xcomp-conf` command line argument. Note that `configure` does not accept
@@ -51,15 +53,13 @@ invoking `make`; otherwise, the environment variables might set make variables
in some applications, or parts of some applications, and you may end up with
an erroneously configured build.
-What can be Cross Compiled?
----------------------------
+### What can be Cross Compiled? ###
All Erlang/OTP applications except the `wx` application can be cross compiled.
The build of the `wx` driver will currently be automatically disabled when
cross compiling.
-Compatibility
--------------
+### Compatibility ###
The build system, including cross compilation configuration variables used,
may be subject to non backward compatible changes without prior notice.
@@ -68,8 +68,7 @@ systems, but has only been partly tested for more esoteric platforms. The
VxWorks example file is highly dependent on our environment and is here more
or less only for internal use.
-Patches
--------
+### Patches ###
Please submit any patches for cross compiling in a way consistent with this
system. All input is welcome as we have a very limited set of cross compiling
@@ -91,13 +90,13 @@ General information on how to submit patches can be found at:
Build and Install Procedure
---------------------------
-If you are building in Git you want to read the "Building in Git" section
-of [`$ERL_TOP/INSTALL.md`] [1] before proceeding.
+If you are building in Git, you want to read the [Building in Git][] section
+of [$ERL_TOP/INSTALL.md][] before proceeding.
We will first go through the `configure`/`make` build procedure which people
probably are most familiar with.
-### Building With `configure`/`make` Directly ###
+### Building With configure/make Directly ###
(1)
@@ -116,7 +115,8 @@ cross compiling in, you currently need a full Erlang/OTP system of the same
release as the one being built for the build machine. If this is the case,
build and install one for the build machine (or use one already built) and add
it to the `$PATH` before cross building, and building the documentation. See
-[`$ERL_TOP/INSTALL.md`] [1] for information on building the documentation.
+the [How to Build the Documentation][] section in the [$ERL_TOP/INSTALL.md][]
+document for information on how to build the documentation.
If you want to build using a compatible Erlang/OTP system in the `$PATH`,
jump to (3).
@@ -152,24 +152,27 @@ build on. If you execute `$ERL_TOP/erts/autoconf/config.guess`, it will in
most cases print the triplet you want to use for this.
Pass the cross compilation variables as command line arguments to `configure`
-using a `<VARIABLE>=<VALUE>` syntax. Note that you can *not* pass a
-configuration file using `--xcomp-conf=<FILE>` when you invoke `configure`
-directly. The `--xcomp-conf=<FILE>` argument can only be passed to
-`otp_build configure`.
+using a `<VARIABLE>=<VALUE>` syntax.
+
+> *NOTE*: You can *not* pass a configuration file using the `--xcomp-conf`
+> argument when you invoke `configure` directly. The `--xcomp-conf` argument
+> can only be passed to `otp_build configure`.
`make` will verify that the Erlang/OTP system used when building is of the
same release as the system being built, and will fail if this is not the case.
It is possible, however not recommended, to force the cross compilation even
though the wrong Erlang/OTP system is used. This by invoking `make` like this:
-`make ERL_XCOMP_FORCE_DIFFERENT_OTP=yes`. Note that this build might fail,
-silently produce suboptimal code, or silently produce erroneous code.
+`make ERL_XCOMP_FORCE_DIFFERENT_OTP=yes`.
+
+> *WARNING*: Invoking `make ERL_XCOMP_FORCE_DIFFERENT_OTP=yes` might fail,
+> silently produce suboptimal code, or silently produce erroneous code.
#### Installing ####
You can either install using the installation paths determined by `configure`
(4), or install manually using (5).
-##### Installing Using Paths Determined by `configure` #####
+##### Installing Using Paths Determined by configure #####
(4)
@@ -179,7 +182,7 @@ You can either install using the installation paths determined by `configure`
`configure` arguments specifying where the installation should reside are for
example: `--prefix`, `--exec-prefix`, `--libdir`, `--bindir`, etc. By default
it will install under `/usr/local`. You typically do not want to install your
-cross build under `/usr/local` on your build machine. Using [`DESTDIR`] [2]
+cross build under `/usr/local` on your build machine. Using [DESTDIR][]
will cause the installation paths to be prefixed by `$DESTDIR`. This makes it
possible to install and package the installation on the build machine without
having to place the installation in the same directory on the build machine as
@@ -249,7 +252,7 @@ or:
$ cd <ABSOLUTE_INSTALL_DIR_ON_TARGET>
$ ./Install [-minimal|-sasl] <ABSOLUTE_INSTALL_DIR_ON_TARGET>
-### Building With the `otp_build` Script ###
+### Building With the otp\_build Script ###
(8)
@@ -297,13 +300,13 @@ visible throughout the whole execution of all `configure` scripts. Other
variables needs to be defined as arguments to `configure` or exported in
the environment.
-### Variables for `otp_build` Only ###
+### Variables for otp\_build Only ###
Variables in this section are only used, when configuring Erlang/OTP for
cross compilation using `$ERL_TOP/otp_build configure`.
-*NOTE*! These variables currently have *no* effect if you configure using
-the `configure` script directly.
+> *NOTE*: These variables currently have *no* effect if you configure using
+> the `configure` script directly.
* `erl_xcomp_build` - The build system used. This value will be passed as
`--build=$erl_xcomp_build` argument to the `configure` script. It does
@@ -354,9 +357,9 @@ All variables in this section can also be used when native compiling.
* `LIBS` - Libraries.
-#### *D*ynamic *E*rlang *D*river Linking ####
+#### Dynamic Erlang Driver Linking ####
-*NOTE*! Either set all or none of the `DED_LD*` variables.
+> *NOTE*: Either set all or none of the `DED_LD*` variables.
* `DED_LD` - Linker for Dynamically loaded Erlang Drivers.
@@ -367,7 +370,7 @@ All variables in this section can also be used when native compiling.
#### Large File Support ####
-*NOTE*! Either set all or none of the `LFS_*` variables.
+> *NOTE*: Either set all or none of the `LFS_*` variables.
* `LFS_CFLAGS` - Large file support C compiler flags.
@@ -403,12 +406,15 @@ All variables in this section can also be used when native compiling.
### Optional Feature, and Bug Tests ###
These tests cannot (always) be done automatically when cross compiling. You
-usually do not need to set these variables. Only set these if you really
-know what you are doing.
+usually do not need to set these variables.
-Note that some of these values will override results of tests performed
-by `configure`, and some will not be used until `configure` is sure that
-it cannot figure the result out.
+> *WARNING*: Setting these variables wrong may cause hard to detect
+> runtime errors. If you need to change these values, *really* make sure
+> that the values are correct.
+
+> *NOTE*: Some of these values will override results of tests performed
+> by `configure`, and some will not be used until `configure` is sure that
+> it cannot figure the result out.
The `configure` script will issue a warning when a default value is used.
When a variable has been set, no warning will be issued.
@@ -483,24 +489,35 @@ When a variable has been set, no warning will be issued.
Copyright and License
---------------------
-> %CopyrightBegin%
->
-> Copyright Ericsson AB 2009-2010. All Rights Reserved.
->
-> The contents of this file are subject to the Erlang Public License,
-> Version 1.1, (the "License"); you may not use this file except in
-> compliance with the License. You should have received a copy of the
-> Erlang Public License along with this software. If not, it can be
-> retrieved online at http://www.erlang.org/.
->
-> Software distributed under the License is distributed on an "AS IS"
-> basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-> the License for the specific language governing rights and limitations
-> under the License.
->
-> %CopyrightEnd%
-
-
-
- [1]: INSTALL.html "$ERL_TOP/INSTALL.md"
- [2]: http://www.gnu.org/prep/standards/html_node/DESTDIR.html "DESTDIR"
+%CopyrightBegin%
+
+Copyright Ericsson AB 2009-2010. All Rights Reserved.
+
+The contents of this file are subject to the Erlang Public License,
+Version 1.1, (the "License"); you may not use this file except in
+compliance with the License. You should have received a copy of the
+Erlang Public License along with this software. If not, it can be
+retrieved online at http://www.erlang.org/.
+
+Software distributed under the License is distributed on an "AS IS"
+basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+the License for the specific language governing rights and limitations
+under the License.
+
+%CopyrightEnd%
+
+Modifying This Document
+-----------------------
+
+Before modifying this document you need to have a look at the
+`$ERL_TOP/README.md.txt` document.
+
+
+
+ [$ERL_TOP/INSTALL.md]: INSTALL
+ [Building in Git]: INSTALL#How-to-Build-and-Install-ErlangOTP_Building-in-Git
+ [How to Build the Documentation]: INSTALL#The-ErlangOTP-Documentation_How-to-Build-the-Documentation
+ [cross configuration variables]: #Currently-Used-Configuration-Variables
+ [DESTDIR]: http://www.gnu.org/prep/standards/html_node/DESTDIR.html
+
+ [?TOC]: true